Codeforces 467C George and Job | DP
题目大意:给定一个长度为n的序列,从序列中选出k个不重叠且连续的m个数,要求和最大。
解题思路:dp[i][j]表示到第i个位置选了j个子序列的最大值;可由两个状态转移来:1.保持上一个位置最大值 2.=上一个子序列位置
#include "bits/stdc++.h" using namespace std; #define rep(i, s, n) for(int i=s;i<n;i++) #define LL long long #define ll __int64 #define INF 0x3f3f3f3f #define PI acos(-1.0) #define E 2.71828 #define MOD 1000000007 #define NN 110 typedef pair<int, int> PII; const int maxn = 5005; int N, M, K; ll arr[maxn], sum[maxn]; ll dp[maxn][maxn]; ll solve () { ll ret = 0; for (int i = M; i <= N; i++) { ll tmp = sum[i] - sum[i-M]; for (int j = 1; j <= K; j++) dp[i][j] = max(dp[i-1][j], dp[i-M][j-1] + tmp); ret = max(ret, dp[i][K]); } /*rep(i,M,N+1){ rep(j,1,K+1){ printf("%d ",dp[i][j]); } printf("\n"); }*/ return ret; } int main () { #ifdef ___LOCAL_WONZY___ freopen("input.txt", "r", stdin); freopen("out.txt", "w", stdout); #endif // ___LOCAL_WONZY___ while(~scanf("%d%d%d", &N, &M, &K)){ for (int i = 1; i <= N; i++) { scanf("%I64d", &arr[i]); sum[i] = sum[i-1] + arr[i]; } printf("%I64d\n", solve()); } return 0; }
参考:http://blog.csdn.net/keshuai19940722/article/details/39585219