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