Codeforces 467C George and Job(dp)

求k个不覆盖的最大连续区间和,每个区间长度为m。

影响决策的因素有k和区间和,所以dp[i][j]的含义就显而易见了,表示在以第i个数的位置选择了j个子序列的最大值。

那么根据递推关系不难写出递推表达式dp[i][j] = max(dp[i-1][j],dp[i-m][j-1]+sum[i]);其中dp[i-1][j]的作用值得我们细细品味,它的作用是将状态转移过来。

而且因为区间的不覆盖性,我们要先枚举位置,再枚举子序列的个数。  

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#include<vector>
#include<set>
#include<map>
#include<cmath>
using namespace std;
typedef long long ll;
ll n,m,k,a[5005],dp[5005][5005],sum[5005];
int main(){
    cin>>n>>m>>k;
    for(int i=1;i<=n;i++) cin>>a[i];
    memset(dp,0,sizeof(dp));
    memset(sum,0,sizeof(sum));
    for(int i=m;i<=n;i++){
        for(int j=i;j>=i-m+1;j--){
            sum[i] += a[j];
        }
    }
    for(int i=m;i<=n;i++){
        for(int j=1;j<=k;j++){
            dp[i][j] = max(dp[i-1][j],dp[i-m][j-1]+sum[i]);
        }
    }
    printf("%lld\n",dp[n][k]);
    return 0;
}


你可能感兴趣的:(ACM,codeforces)