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\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 */

 

你可能感兴趣的:(codeforces)