01背包 Codeforces Round #267 (Div. 2) C. George and Job

题目传送门

 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
", 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 */
编译人生,运行世界!
原文地址:https://www.cnblogs.com/Running-Time/p/4561777.html