Educational Codeforces Round 63 (Rated for Div. 2) D题

题目网址:https://codeforc.es/contest/1155/problem/D

题目大意:给定n个数和一个k,可以对这n个数进行一次操作,也可以不进行,即选择某个区间中的数都乘上k,问最后最大连续子段和是多少?

题解:(鶸鶸的我是看别人的博客才解决的 ! )

首先这道题的状态很多,对于前m个数,乘k之前的状态,乘k的状态,之和的状态都需要建立。那么分别设dp1,dp2,dp3是乘k之前,乘k时,乘k之和,前m个数最大连续子段和。

首先对于dp1,即一组数的最大子段和,显然只要是正数就可以加,即dp1=max(0,dp1+value),对于dp2,在乘k时,有两种选择,乘或者不乘,不乘的状态就是继承dp1,即dp2=max(dp1,dp2+value*x)

对于乘过之后,是继承dp2的状态,即和dp1差不多,所以dp3=max(dp2,dp3+value)

 1 #include<bits/stdc++.h>
 2 #define ll long long
 3 using namespace std;
 4 ll dp1=0,dp2=0,dp3=0;
 5 int main()
 6 {
 7     ll n,x,val,res=-1e19;
 8     cin>>n>>x;
 9     for(int i=1;i<=n;i++) {
10         scanf("%I64d",&val);
11         dp1=max(0ll,dp1+val);//是第k段在没有操作之前的最大和
12         dp2=max(dp1,dp2+val*x);//是第k段操作时的最大和
13         dp3=max(dp2,dp3+val);
14         res=max(dp3,res); 
15     }
16     cout<<res<<endl;
17     return 0;
18 }  
View Code

猜你喜欢

转载自www.cnblogs.com/duxing201806/p/10805677.html