给n个数,问把这个数列分为k段长度为m的区间的元素之和的最大值是多少。
dp[i][j]由dp[i - 1][j]不添加区间或者由dp[i - m][j - 1]添加长度为m的区间得到。
状态转移方程:dp[i][j] = max(dp[i - 1][j], dp[i - m][j - 1] + b[i] - b[i - m])
AC代码:
#include "iostream"
#include "cstdio"
#include "cstring"
#include "algorithm"
using namespace std;
const int MAXN = 5005;
typedef long long ll;
ll dp[MAXN][MAXN], a[MAXN], b[MAXN];
int n, m, k;
int main(int argc, char const *argv[])
{
scanf("%d%d%d", &n, &m, &k);
for(int i = 1; i <= n; ++i) {
scanf("%I64d", &a[i]);
b[i] = b[i - 1] + a[i];
}
for(int i = m; i <= n; ++i)
for(int j = 1; j <= k; ++j)
dp[i][j] = max(dp[i - 1][j], dp[i - m][j - 1] + b[i] - b[i - m]);
printf("%I64d\n", dp[n][k]);
return 0;
}