HDU 1024 Max Sum Plus Plus(DP)

HDU 1024 Max Sum Plus Plus

传送门

题意

求一段序列的m个子段的最大和

思路

1.DP
2.对于每一个数,分类讨论它是属于前一个子段或者是单独成段。
3.状态转移方程
dp[i][j]=以j结尾的有i段子段的最大和
dp[i][j]=Max(dp[i][j-1]+a[j] , Max( dp[i-1][k] ) + a[j] ) 0<k<j

但是这么搞会TLE,所以要优化到O(n^2)。
记pre[j]=(i-1)个子段时dp[i-1][k](k:1)的最大值,为下次计算所用。

代码

#include<cstdio>
#include<algorithm>

using namespace std;

const int maxn=1000000+100;
const int inf=0x3f3f3f3f;
int a[maxn],f[maxn],pre[maxn];

int main(){
//  freopen("AAA.in","r",stdin);
    int n,m;
    while(~scanf("%d%d",&m,&n)){
        for(int i=1;i<=n;i++){
            scanf("%d",&a[i]);
            f[i]=pre[i]=0;
        }
        int mx;
        for(int i=1;i<=m;i++){
            mx=-inf;
            for(int j=i;j<=n;j++){
                f[j]=max(f[j-1]+a[j],pre[j-1]+a[j]);
                pre[j-1]=mx;
                mx=max(mx,f[j]);
            }
        }
        printf("%d
",mx);
    }
    return 0;
}

后记

用pre优化时间的时候,发现空间也可以顺便优化了。

原文地址:https://www.cnblogs.com/yohanlong/p/6058151.html