CF 467C DP George and Job

来源:互联网 发布:中标软件 编辑:程序博客网 时间:2024/06/15 14:06


转移方程

d[i+1] [j] =  s[j+m-1] - s[j-1] + max ( d[i] [x]), (1<=x<=j-m)


d[i] [j] 表示第i个区间以第j个数开始的最大值。

另外后面求最大值有个优化方法,因为每一次j总增加1,也就是x只增加1个值,所以只需把当前的和最大值比较就可以了。


#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>#include <algorithm>#include <cmath>#include <string>#include <vector>#include<map>#define pi acos(-1.0)#define eps 1e-6#define inf 1<<30#define INF 1ll<<60#define ll long long#define MOD 1000000007using namespace std;int a[5010];ll d[5010][5010];ll s[5010];int main(){    int n,m,k;    scanf("%d%d%d",&n,&m,&k);    for(int i=1; i<=n; i++)        scanf("%d",&a[i]);    s[0]=0;    s[1]=a[1];    for(int i=2; i<=n; i++)        s[i]=s[i-1]+a[i];    for(int i=1; i+m-1+(k-1)*m<=n; i++)        d[1][i]=s[i+m-1]-s[i-1];    for(int i=1; i<=k-1; i++)    {        ll Max=0;        for(int j=1; j<=n; j++)        {//            for(int p=1; p+m<=j; p++)//            {//                Max=max(Max,d[i][p]);//            }            if(j-m>=1)           //优化方法                Max=max(Max,d[i][j-m]);            else                Max=0;            d[i+1][j]=Max+s[j+m-1]-s[j-1];        }    }    ll  ans=0;    for(int i=1; i<=n; i++)        ans=max(ans,d[k][i]);    printf("%I64d\n",ans);    return 0;}


0 0