小破題!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 }