题目链接
http://codeforces.com/contest/1155/problem/D
题意:
首先给你两个整数n和x;
然后输入n个整数。
有最多一次操作,让某个区间的所有值都乘x。也可以不进行这个操作。
然后求出最大的区间和。
题解
动态规划题。
dp[i][0] 表示以a[i]结尾,并且没有进行乘x操作的最大值。
dp [i][1]表示以a[i]*x结尾的最大值。
dp[i][2]表示以a[i]结尾的最大值(前边可能进行乘x操作了,也可能没进行乘x操作、这种情况包括了dp[i][0])。
那么以a[i]结尾的最大值就是max(dp [i][1],dp[i][2])
状态转移方程为:
dp[i][0]=max(dp[i-1][0]+a[i],a[i]);
dp[i][1]=max(max(dp[i-1][1]+a[i]*x,a[i]*x),dp[i-1][0]+a[i]*x);
dp[i][2]=max(max(dp[i][0],dp[i-1][1]+a[i]),dp[i-1][2]+a[i]);
代码
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
typedef long long ll;
const int maxn=3e5+5;
int n,x;
ll dp[maxn][4];
int main(){
cin>>n>>x;
ll ans=0;
for(int i=1;i<=n;i++){
ll a;
scanf("%lld",&a);
dp[i][0]=max(dp[i-1][0]+a,a);
dp[i][1]=max(max(dp[i-1][1]+a*x,a*x),dp[i-1][0]+a*x);
dp[i][2]=max(max(dp[i][0],dp[i-1][1]+a),dp[i-1][2]+a);
ans=max(max(ans,dp[i][1]),dp[i][2]);
}
if(ans<0) printf("0\n");
else printf("%lld\n",ans);
return 0;
}