题目大意:
有一组数p,选择k组数,每组数是连续的m个数,求最后的大小,看样例比较好理解。
思路:
一开始我的想法便想到了dp[i][j]表示的是到i这个位置,已经取了j组数时候的最大和。
不过接下来的想法跟我的代码实现不大一致,想法没错。
我是想要求dp[i][j],那么他就等于前面dp[k][j-1]+p[i-m~i]
或者是直接从前面dp[k][j]中选择最大的过来。
在代码的实现过程当中过于偏执,考虑到j-1组的开始和终点有一个界限,于是便在这个界限去遍历
殊不知,小于这个界限的,便是0,可有可无,想多了反而更加的复杂。
在者是犯的第二个错误。
并没有想到如何去表示一个区间和,最好的方法便是p[i]表示的是1到i的和
需要哪一段,便去相加减即可。
以致于写的颇为坎坷。
看来今日不宜刷题,得好好反省反省这且燥的心。
感谢美辰巨巨提供的好题~
AC代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
long long dp[5005][5005];
long long p[5005];
int main()
{
int n, m, k;
while (cin >> n >> m >> k)
{
p[0] = 0;
for (int i = 1; i <= n; i++)
{
scanf("%d", &p[i]);
p[i] += p[i - 1];
}
memset(dp, 0, sizeof(dp));
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] + p[i] - p[i - m]);
}
cout << dp[n][k] << endl;
}