揹包問題簡單使用,利用滾動數組法能夠實現,由於題目中還提到在歌曲數目相同的狀況下儘量時間久,這時候就能夠引入另外一個DP數組tdp記錄策略所對應的歌曲時間。
須要注意的是,tdp的大小關係的定義:ios
#include <cstdio> #include <iostream> #include <algorithm> #include <cstring> #include <queue> #include <cmath> #include <vector> using namespace std; const int maxn= 55; const int maxt= 180*maxn; const int GJJ= 678; int dp[maxt], tdp[maxt]; int s[maxn]; void Init(int t) { for (int i= t; i> 0; --i){ dp[i]= s[1]< i ? 1 : 0; tdp[i]= dp[i] ? GJJ+s[1] : GJJ; } } int main() { int T, n, t, kase; scanf("%d", &T); for (kase= 1; kase<= T; ++kase){ scanf("%d %d", &n, &t); for (int i= 1; i<= n; ++i){ scanf("%d", s+i); } Init(t); for (int i= 2; i<= n; ++i){ for (int j= t; j> 0; --j){ if (s[i]>= j){ continue; } if (dp[j-s[i]]+1> dp[j]){ dp[j]= dp[j-s[i]]+1; tdp[j]= tdp[j-s[i]]+s[i]; } else if (dp[j-s[i]]+1== dp[j] && tdp[j-s[i]]+s[i]> tdp[j]){ tdp[j]= tdp[j-s[i]]+s[i]; } } } printf("Case %d: %d %d\n", kase, dp[t]+1, tdp[t]); } return 0; }