题意:求在给定时间内,最多能唱多少歌曲,在最多歌曲的情况下,使唱的时间最长。
该题类似于01背包问题,可用01背包问题的解题思路来求,每个歌曲相当于物品,歌曲的长度相等于物品重量,每个歌曲的“价值”为1。由于金歌劲曲时间最长,所以最后要留至少1秒时间开始唱金歌劲曲,所以计算t-1时间内最多唱的歌曲和时间,最终答案为歌曲数加1,时间加上金歌劲曲的时间。
需要注意的是,由于要求是连续唱歌,所以在计算某个时间最多唱的歌曲时,必须是该时间内恰好唱完这些歌,时间多了不行。这与01背包不同。
代码如下:
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 5 using namespace std; 6 7 const int MAXN = 10000; 8 int f[MAXN], t[55]; 9 10 int main() 11 { 12 int T, n, cas, i, j, len, ma; 13 scanf("%d", &T); 14 for(cas = 1; cas <= T; cas++) 15 { 16 scanf("%d%d", &n, &len); 17 len--; //留最后一秒开始唱金歌劲曲 18 for(i = 1; i <= n; i++) 19 { 20 scanf("%d", &t[i]); 21 } 22 memset(f, 0, sizeof(f)); 23 ma = 0; 24 for(i = 1; i <= n; i++) 25 { 26 for(j = len; j >= t[i]; j--) 27 { 28 if(f[j - t[i]] >= 1|| j == t[i]) //在j时间内可以唱完第i首歌。 29 { 30 f[j] = max(f[j], f[j - t[i]] + 1); 31 ma = max(ma, f[j]); 32 } 33 } 34 } 35 for(i = len; i >= 0; i--) //寻找唱最多歌情况下,时间最长的那个 36 { 37 if(f[i] == ma) 38 break; 39 } 40 if(ma == 0) //在给定时间内无法唱完任何一首歌 41 printf("Case %d: %d %d\n", cas, 1, 678); 42 else 43 printf("Case %d: %d %d\n", cas, 1 + ma, i + 678); 44 } 45 return 0; 46 }
时间: 2024-10-09 00:14:20