背包问题简单使用,利用滚动数组法能够实现,由于题目中还提到在歌曲数目相同的状况下尽量时间久,这时候就能够引入另外一个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; }