CF267 div2 C 区间DP

来源:互联网 发布:dotamax数据更新 编辑:程序博客网 时间:2024/06/06 11:42

题意:很经典的最大k段不相交子序列和问题 要求是使得这个和最大 求出这个和的值

解法:开始的时候想一维来做的 然后写完了发现会有重复选择的问题 这个纸上把第二个

例子写一下就很清楚了 但是当时我没有这么做 然后我们发现状态只能增加了 为了不产生重叠部分 只能加上一维结尾的位置 然后就变成dp[k][len]

这样的话直接推就没有什么鸭梨了 但是我又在脑子里面yy了一下 这样写直接 n*n似乎会比较大 然后当没还没有超时的

于是我又增加了限制范围就是取第k个段的合法的范围 然后这样一些比较奇葩了 表示写完以后比n*n

还要略大sad

#include<cstdio>#include<iostream>#include<string.h>#include<algorithm>#include<stdio.h>#include<limits.h>using namespace std;#define ll __int64#define maxn 5555int n,m,k;ll sum[maxn],x[maxn],ans[5000][5000];int main(){    scanf("%d%d%d",&n,&m,&k);    for(int i=1;i<=n;++i){        scanf("%I64d",&x[i]);        sum[i]=sum[i-1]+x[i];    }    memset(ans,0,sizeof ans);    ll tot,mi;    for(int t=1;t<=k;++t){        mi=sum[t*m]-sum[t*m-m];        tot=mi-x[t*m];        for(int i=t*m;i<=n-(k-t)*m;++i){            tot+=x[i];            ans[t][i]=max(ans[t][i-1],ans[t-1][i-m]+tot);            tot-=x[i-m+1];        }    }    printf("%I64d\n",ans[k][n]);    return 0;}



0 0
原创粉丝点击