UVa12563 -Jin Ge Jin Qu hao.
题意:有n首歌(劲歌金曲除外),每首歌都有一个时间,然后给定一个时间t,问在给定的时间内最多能唱的歌曲数目以及能唱的最长时间,如果已经到了时间限制t,但是还没唱完,那么可以唱完这首歌。
分析:每首歌最多180秒,而劲歌金曲有678s,首先得保证唱的歌曲数目最多,之后保证时间更长。
留1s唱劲歌金曲就行了。然后就是个01背包,只是规划时根据题目要求来就行了。
这个题目中t给定的范围很大,看似无法进行DP,但是这个分析题目便可以知道总共唱的时间不会超过180*n+678,所以不存在问题,之前做一个题目poj3260时就被坑过,根据数据估计的范围很大,时间复杂度难以承受,但是就题目本身而言,分析可知根本不可能达到这么大,所以还是可以在时间范围解决的。
有些题目总会存在各种各样的坑点,看似无法解决,其实只差一步而已。
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <cmath>
#define INF 0x3f3f3f3f
#define LL long long
using namespace std;
struct st
{
int cnt, time;
}dp[100000];
int a[100];
int main()
{
int t, k = 0, n, T, sum;
scanf("%d", &t);
while (t--){
scanf("%d %d", &n, &T);
sum = 0;
for (int i = 0; i < n; i++) scanf("%d", a+i), sum += a[i];
int tmp = min(T-1, sum);
memset(dp, 0, sizeof(dp));
for (int i = 0; i < n; i++){
for (int j = tmp; j >= a[i]; j--){
st &t = dp[j-a[i]], &s = dp[j];
if (t.cnt+1 > s.cnt || (t.cnt+1 == s.cnt && t.time+a[i] > s.time)){
s.cnt = t.cnt+1;
s.time = t.time+a[i];
}
}
}
printf("Case %d: %d %d\n", ++k, dp[tmp].cnt+1, dp[tmp].time+678);
}
return 0;
}