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