Max Sum Plus Plus HDU

递推填表,填出来是个平行四边形;

#include<cstdio>
#include<cctype>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long LL;
const int N=1e6+5;
const int inf=0x3f3f3f3f;
LL f[N],last[N];
///f[i] 记录当前轮(当前段数k)以第i个数结尾的 最大k段和;
///last[i] 记录上一轮前i个f 的最大值;
///f[i][j]=max(f[i][j-1]+a[j],f[i-1][t]+a[j]); i-1<=t<=j-1;
///最少一个数一个段,t>=i-1;
int a[N];
LL read()
{
    LL x=0,t=1;
    char ch=getchar();
    while(!isdigit(ch)){ if(ch=='-')t=-1; ch=getchar(); }
    while(isdigit(ch)){ x=10*x+ch-'0'; ch=getchar(); }
    return x*t;
}
int main()
{
    int n,m;
    while(scanf("%d%d",&m,&n)!=EOF)
    {
        for(int i=1;i<=n;i++)
            a[i]=read();
        memset(f,0,sizeof(f) );
        memset(last,0,sizeof(last) );
        f[0]=-inf;
        ///最大子段和要求至少选一个物品,f[0]没有物品可选,初始化-inf;
        ///初始化时,last的值记录i-1=0的最大值,段数为0,因此last=0;
        ///f记录段数0的最大值,f=0;
        LL maxn;
        for(int i=1;i<=m;i++)
        {
            maxn=-inf;
            for(int j=i;j<=n;j++)
            {
                f[j]=max(f[j-1],last[j-1])+a[j];
                last[j-1]=maxn;
                maxn=max(maxn,f[j]);

            }
        }
        printf("%lld
",maxn);
    }
    return 0;
}

错点:
f[i]是以第i个数为结尾的最优解,所以到第m轮的时候,ans=max(f[k],ans), m<=k<=n;

原文地址:https://www.cnblogs.com/DeepJay/p/12025203.html