洛谷P2736 「破鑼搖滾」樂隊 Raucous Rockers

小破題!ide

有劇毒。優化

三維的DP方程,能夠優化到二維,還有奇淫技巧用一維。spa

我固然是選擇三維啦!code

f[i][j][k]表示前i首歌前j張CD的k空間,最多能放下的歌數。blog

決策:string

1.放棄這首歌,此時 f[i][j][k] = f[i - 1][j][k]it

2.放到這張CD裏(若是放得下),此時 f[i][j][k] = f[i - 1][j][k - cost[i]]io

3.放到上一張CD裏(若是j > 1),此時 f[i][j][k] = f[i - 1][j - 1][t - cost[i]]event

而後按照 i j k 的順序循環,答案就是 max(f[n][j][k])class

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 using std::max;
 5 const int N = 30;
 6 
 7 int cost[N], f[N][N][N];
 8 
 9 int main() {
10     int n = 0, t, m, p, x;
11     //memset(f, 0xcf, sizeof(f));
12     scanf("%d%d%d", &p, &t, &m);
13     for(int i = 1; i <= p; i++) {
14         scanf("%d", &x);
15         if(x <= t) {
16             cost[++n] = x;
17         }
18     }
19 
20     f[0][1][0] = 0;
21     for(int i = 1; i <= n; i++) {
22         for(int j = 1; j <= m; j++) {
23             for(int k = 0; k <= t; k++) {
24                 if(cost[i] <= k) {
25                     f[i][j][k] = max(f[i - 1][j][k], f[i - 1][j][k - cost[i]] + 1);
26                 }
27                 else if(j > 1) {
28                     f[i][j][k] = max(f[i - 1][j - 1][t - cost[i]] + 1, f[i - 1][j][k]);
29                 }
30                 else {
31                     f[i][j][k] = f[i - 1][j][k];
32                 }
33             }
34         }
35     }
36 
37     int ans = -1;
38     for(int i = 1; i <= m; i++) {
39         for(int j = 1; j <= t; j++) {
40             ans = max(ans, f[n][i][j]);
41         }
42     }
43     printf("%d", ans);
44     return 0;
45 }
AC代碼
相關文章
相關標籤/搜索