CF1155D Beautiful Array
题意:给你n个数和一个系数,你可以选择一个区间乘上这个系数,最后算出这些数的最大子段和
0:当前这个数不*k,且前面的数都没*k
1:当前这个数*k,
2:当前这个数不*k,且前面的数有*k
因为可以舍去前一部分最大值为负数的数列不要,只取一段字串,所以每一个状态还可以依赖于0。
对应转移方程
dp[i][0]=max(0LL,dp[i-1][0])+x; dp[i][1]=max(dp[i-1][0],dp[i-1][1])+x*k; dp[i][2]=max(dp[i-1][1],dp[i-1][2])+x;
代码
#include#include #include using namespace std; typedef long long LL; const int N=300010; LL n,k,ans=0,a[N],dp[N][5]; int main(){ scanf("%lld%lld",&n,&k); for(int i=1;i<=n;++i){ LL x; scanf("%lld",&x); dp[i][0]=max(0LL,dp[i-1][0])+x; dp[i][1]=max(0LL,max(dp[i-1][0],dp[i-1][1]))+x*k; dp[i][2]=max(0LL,max(dp[i-1][1],dp[i-1][2]))+x; ans=max(dp[i][0],ans); ans=max(dp[i][1],ans); ans=max(dp[i][2],ans); } printf("%lld\n",ans); return 0; }
https://www.cnblogs.com/BakaCirno/p/10758491.html
还有一个不是很明白的代码:
https://www.cnblogs.com/hitgxz/p/10754260.html
https://blog.csdn.net/qq_41037114/article/details/89500879
#include#define ll long long using namespace std; ll n,k,x; ll dp[10],ans; int main(){ scanf("%lld%lld",&n,&k); for(int i=1;i<=n;i++) { scanf("%lld",&x); dp[0]=max(1LL*0,dp[0]+x); //最大字段和 dp[1]=max(dp[0],dp[1]+x*k); //前面的最大字段和+当前的数要乘系数 dp[2]=max(dp[1],dp[2]+x); //前面两段的和再加上当前的数不乘系数 ans=max(ans,dp[2]); } printf("%lld\n",ans); return 0; } ———————————————— 版权声明:本文为CSDN博主「Cherry_0525」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/qq_41037114/article/details/89500879