UVa12563(DP)

   题意:求在给定时间内,最多能唱多少歌曲,在最多歌曲的情况下,使唱的时间最长。

      该题类似于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 }

 

你可能感兴趣的:(uva)