标签:
1 /*
2 题意:选择k个m长的区间,使得总和最大
3 01背包:dp[i][j] 表示在i的位置选或不选[i-m+1, i]这个区间,当它是第j个区间。
4 01背包思想,状态转移方程:dp[i][j] = max (dp[i-1][j], dp[i-m][j-1] + sum[i] - sum[i-m]);
5 在两个for循环,每一次dp[i][j]的值都要更新
6 */
7 #include <cstdio>
8 #include <cstring>
9 #include <algorithm>
10 #include <cmath>
11 using namespace std;
12
13 typedef long long ll;
14 const int MAXN = 5e3 + 10;
15 const int INF = 0x3f3f3f3f;
16 ll a[MAXN];
17 ll sum[MAXN];
18 ll dp[MAXN][MAXN];
19
20 int main(void) //Codeforces Round #267 (Div. 2) C. George and Job
21 {
22 int n, m, k;
23 while (scanf ("%d%d%d", &n, &m, &k) == 3)
24 {
25 memset (sum, 0, sizeof (sum));
26 for (int i=1; i<=n; ++i) {scanf ("%I64d", &a[i]); sum[i] = sum[i-1] + a[i];}
27
28 ll ans = 0;
29 for (int i=m; i<=n; ++i)
30 {
31 ll tmp = sum[i] - sum[i-m];
32 for (int j=1; j<=k; ++j)
33 {
34 dp[i][j] = max (dp[i-1][j], dp[i-m][j-1] + tmp);
35 }
36 ans = max (ans, dp[i][k]);
37 }
38
39 printf ("%I64d\n", ans);
40 }
41
42
43 return 0;
44 }
45
46 /*
47 5 2 1
48 1 2 3 4 5
49 7 1 3
50 2 10 7 18 5 33 0
51 */
01背包 Codeforces Round #267 (Div. 2) C. George and Job
标签:
原文地址:http://www.cnblogs.com/Running-Time/p/4561777.html