描述:
略
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
int song[55],d[55][180 * 50 + 678];//前i首歌,刚好是j秒的最多歌数,这样就和01背包一样啦。
int main(){
//freopen("d://poj//data.txt","w",stdout);
int T,n,t,i,j;
scanf("%d",&T);
for(int p = 0;p < T; ++p){
scanf("%d%d",&n,&t);
for(i = 1;i <= n; ++i)
scanf("%d",song + i);
sort(song,song + n);
memset(d,-1,sizeof(d));
for(i = 0;i < n; ++i)
d[i][0] = 0;//第一首加入歌单的歌
int cnt = -1;
int sum = 0;
for(i = 1;i <= n; ++i){
for(j = 0;j < t; ++j){
d[i][j] = d[i - 1][j];//之前加入的歌曲
if(j >= song[i] && d[i - 1][j - song[i]] >= 0)//如果j能表示一首歌:第一首歌或者和之前的歌合起来是j
d[i][j] = max(d[i][j],d[i - 1][j - song[i]] + 1);
if(i == n){
if(d[i][j] >= cnt){//因为之前排过序了,所以一定是剩余时间最少的。
cnt = d[i][j];
sum = j;
}
}
}
}
printf("Case %d: %d %d\n",p + 1,cnt + 1,sum + 678);
}
return 0;
}
主要难点还是状态,不过此题还有一个地方,就是题目给出总时间的范围是10e9但显然此题范围不会超过所有歌唱满外加劲歌金曲的时间。