动规-Raucous Rockers

题目如下:

你刚刚得到了流行的“破锣摇滚”乐队录制的尚未发表的N(1 <= N <=20)首歌的版权。你打算从中精选一些歌曲,发行M(1 <= M <= 20)张CD。每一张CD最多可以容纳T(1 <= T <=20)分钟的音乐,一首歌不能分装在两张CD中。

不巧你是一位古典音乐迷,不懂如何判定这些歌的艺术价值。于是你决定根据以下标准进行选择:

歌曲必须按照创作的时间顺序在CD盘上出现。

选中的歌曲数目尽可能地多。

 

INPUTFORMAT

第一行:三个整数:N, T, M.

第二行:N个整数,分别表示每首歌的长度,按创作时间顺序排列。

 

SAMPLEINPUT (file rockers.in)

4 5 2

4 3 4 2

 

OUTPUTFORMAT

一个整数,表示可以装进M张CD盘的乐曲的最大数目。

SAMPLEOUTPUT (file rockers.out)

3

 

 

 

我的方法就是设f[i][j][k]表示在前i张唱片、录到第j分钟、录到第k首歌所录得最多歌曲数,转移方程如下: 

      f[i][j][k]=max{前一分钟的歌曲数,前一首歌的歌曲数,把第k首歌在当前位置放进去的歌曲数(如果可以)

 

       然后因为每张唱片的时间一样,所以可以这样简化: 

       f[i,j]表示在前i首歌中,共录到第j分钟所录得最多歌曲数 

       f[k,i*t+j]:=max{f[k,i*t+j-1],              前一分钟的歌曲数, 

                                f[k-1,i*t+j],           前一首歌的歌曲数 

                                f[k-1,i*t+j-len[k]]+1(len[k]<=j) } 把第k首歌在当前位置放进去的歌曲数 

 

 

代码如下: 

01 /*

02 ID:xpycc1

03 PROG:rockers

04 LANG:C++

05 */

06 

07 #include<fstream>

08 #define MAXN 20

09 #define MAXM 20

10 #define MAXT 20

11 using namespace std;

12 

13 ifstream fin("rockers.in");

14 ofstream fout("rockers.out");

15 

16 int f[MAXM+1][MAXT+1][MAXN+1],len[MAXN+1],n,m,t;

17 

18 int main(){

19     int i,j,k;

20     fin>>n>>t>>m;

21     for(i=1;i<=n;++i)

22         fin>>len[i];

23 

24     for(i=1;i<=m;++i)                             //i张唱片

25         for(j=1;j<=t;++j)                         //j分钟

26             for(k=1;k<=n;++k){                    //k首歌

27                 if(j==1)                          //换唱片

28                     f[i][j][k]=max(f[i][j][k-1],  //前一首歌的歌曲数

29                                    f[i-1][t][k]); //前一分钟的歌曲数(下同)

30                 else                              //没有换唱片

31                     f[i][j][k]=max(f[i][j][k-1], f[i][j-1][k]);

32 

33                 if(len[k]<j)                      //没有换唱片

34                     f[i][j][k]=max(f[i][j][k],

35                 f[i][j-len[k]][k-1]+1);//把第k首歌在当前位置放进去的歌曲数(下同)

36                 if(len[k]==j)                     //换唱片

37                     f[i][j][k]=max(f[i][j][k],   f[i-1][t][k-1]+1);

38           }

39 

40     fout<<f[m][t][n]<<endl;

41     return 0;

42 }

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值