给定一个长度为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; }