CF1077F1 Pictures with Kittens (easy version)(DP)

参考巨巨的博客https://www.cnblogs.com/pkgunboat/p/9974886.html

 

/*
 * CF1077F1
 * 题意:
 * 给你一个n个元素的数组,从中选取X个元素,并且要保证任意的m个位置中至少有一个元素被选中,问选中元素和的最大值。
 * 题解:
 * 设dp[i][j]表示i位置已经选择了j个元素,所有选中元素的最大和。
 * 从i-m+1的位置开始转移,可以写出状态转移方程:
 * dp[i][j] = max(dp[k][j-1])+a[i]
 * 意思是,从i-m+1位置到i-1的位置找到已经选取j-1个元素中和最大的一个,再加上自己。
 * 最后在n-m+1中找最大值就是答案。因为这些点已经被选取,所以保证了最终答案的合法性。
 */
#include<bits/stdc++.h>

using namespace std;
typedef long long ll;
const int maxn=255;
ll dp[maxn][maxn];
ll a[maxn];
int main () {
    int N,M,X;
    cin>>N>>M>>X;
    for (int i=1;i<=N;i++) scanf("%lld",&a[i]);
    int tt=N-M+1;
    if ((tt/M+(tt%M>0))>X) {
        printf("-1\n");
        return 0;
    }
    int cnt=1;
    for(int i=1;i<=N;i++){
        for(int j=cnt;j<=min(i,X);j++){
            for(int k=max(0,i-M);k<i;k++)
                dp[i][j]=max(dp[k][j-1]+a[i],dp[i][j]);
        }
        if (i%M==0) cnt++;
    }
    ll ans=0;
    for (int i=N-M+1;i<=N;i++) ans=max(ans,dp[i][X]);
    printf("%lld\n",ans);
}

 

posted @ 2020-05-21 13:38  zlc0405  阅读(146)  评论(0编辑  收藏  举报