给定一个长度为n的序列,选出k组不重叠且连续的m个数,使其和最大
1<=m*k<=n<=5000(有负数)
dp[i][j] 表示前i个数分为j分的最大值
转移方程为:dp[i][j] = dp[i - 1][j] + dp[i - m][j - 1] + sum[i] - sum[i - m];
dp[i - 1][j] 表示不选择该数
dp[i - m][j - 1] + sum[i] - sum[i - m] 表示选择该数
#include <bits/stdc++.h>
using namespace std;
const int maxn = 5005;
typedef long long ll;
ll a[maxn], sum[maxn];
ll dp[maxn][maxn];
int main() {
int n, m, k;
scanf("%d%d%d", &n, &m, &k);
for (int i = 1; i <= n; i++) scanf("%lld", &a[i]);
for (int i = 1; i <= n; i++) sum[i] = sum[i - 1] + a[i];
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= k; j++) {
if (i >= m) dp[i][j] = max(dp[i - 1][j], dp[i - m][j - 1] + sum[i] - sum[i - m]);
else dp[i][j] = dp[i - 1][j];
}
}
printf("%I64d\n", dp[n][k]);
return 0;
} 
京公网安备 11010502036488号