【51Nod】1052 最大M子段和 DP

来源:互联网 发布:windows 10 一周年 编辑:程序博客网 时间:2024/06/06 07:05

第一眼DP

第二眼隔板法

第三眼。。。

嗯?第二眼好像看偏了?

重新看第二眼

二维DP

所以说这道题是看两眼就可以看出来做法比较裸的DP题

WA了一发以后又重新看了一眼题面

嗯,要开long long

所以说这道题是看三眼就可以AC比较裸的DP题

做完后倒回来看一眼自己的程序

嗯,只用到前面的一维

数组可以循环使用

所以说这道题是看四眼就可以优化程序比较裸的DP题

这话说出来我自己都不信

C++ 109 ms 2116 KB Accepted 2017/10/24 18:28:10 80

#include <cstdio>#define C (c=nc())using namespace std;long long Max[5005],f[2][5005],ans,sum;int a[5005],m,n,cnt,line;long long max(long long a,long long b){    return a>b?a:b;}inline char nc(void){    static char ch[100010],*p1=ch,*p2=ch;    return p1==p2&&(p2=(p1=ch)+fread(ch,1,100010,stdin),p1==p2)?EOF:*p1++;}inline void read(int &n){    static char c;int f=1;n=0;C;    while (c<'0'||c>'9') c=='-'?f=-1,C:C;    while (c>='0'&&c<='9') n=(n<<3)+(n<<1)+c-48,C;    return (void)(n*=f);}int main(void){    freopen ("in.txt","r",stdin);    read(n),read(m);    register int i,j;    for (i=1;i<=n;++i)    {        read(a[i]);        if (a[i]>0) ++cnt;    }    if (cnt<=m)    {        for (i=1;i<=n;++i)        {            if (a[i]>0) sum+=a[i];        }        printf("%lld\n",sum);        return 0;    }    line=0;    for (i=1;i<=m;++i)    {        for (j=1;j<=n;++j)        {            f[line][j]=max(max(f[line][j],f[line][j-1]+a[j]),max(f[line][j],Max[j-1]+a[j]));        }        for (j=1;j<=n;++j)        {            Max[j]=max(Max[j-1],f[line][j]);        }        line^=1;    }    for (i=1;i<=n;++i)    {        ans=max(ans,f[line^1][i]);    }    printf("%lld\n",ans);    return 0;}
原创粉丝点击