题目链接:
[CodeForces 467C]George and Job[DP]
题意分析:
求一个含有n个数的序列,从其中选定k个长度为m的不想交的区间,最大和为多少?(k * m <= n)
解题思路:
设状态为dp[i][j]:前i个数,取j个区间能达到的最大值。
那么就有转移方程:dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - 1] + sum[i] - sum[i - m]); // sum为前缀和
整个就是区间区和不取的关系。
对了,不要忘了开long long XD
个人感受:
现在看来,这就是背包啊= =。竟然没想到= =。当时想了一个状态,取i个长度为j的区间,233。趁着年末赶紧写篇题解,考试什么的也都快告一段落了,好好刷题(☆_☆)
具体代码如下:
#include<iostream>
#define ll long long
using namespace std;
const int MAXN = 5e3 + 11;
ll dp[MAXN][MAXN];
ll sum[MAXN];
int main()
{
int n, m, k;
cin >> n >> m >> k;
for (int i = 1; i <= n; ++i) {
cin >> sum[i];
sum[i] += sum[i - 1];
}
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] + sum[i] - sum[i - m]);
}
cout << dp[n][k] << '\n';
return 0;
}