USACO3.4.4--Raucous Rockers

Raucous Rockers

You just inherited the rights to N (1 <= N <= 20) previously unreleased songs recorded by the popular group Raucous Rockers. You plan to release a set of M (1 <= M <= 20) compact disks with a selection of these songs. Each disk can hold a maximum of T (1 <= T <= 20) minutes of music, and a song can not overlap from one disk to another.

Since you are a classical music fan and have no way to judge the artistic merits of these songs, you decide on the following criteria for making the selection:

  • The songs on the set of disks must appear in the order of the dates that they were written.
  • The total number of songs included will be maximized.

PROGRAM NAME: rockers

INPUT FORMAT

Line 1: Three integers: N, T, and M.
Line 2: N integers that are the lengths of the songs ordered by the date they were written.

SAMPLE INPUT (file rockers.in)

4 5 2
4 3 4 2

OUTPUT FORMAT

A single line with an integer that is the number of songs that will fit on M disks.

SAMPLE OUTPUT (file rockers.out)

3
题解:这题可以用动态规划来做也可以用枚举来做。
第一种方法:枚举(可以参考byvoid大牛的解析)。枚举量为2^20=1048576(时间上还是允许的),即在N首歌的所有非空子集,然后算出每种情况所有光盘上能够刻录的歌曲总数目,记录最大值即可。可以用位运算来做,非常的简单和直白。
第二种方法:动态规划。定义一个三维数组f.
状态转移方程为:f[i][j][k]=max(f[i-1][j][k],f[i][j-1][k])(time[i]>k)
Or max(f[i-1][j][k-time[i]]+1,f[i-1][j-1][T]+1)(time[i]<=k)
f[i][j][k]表示前i首歌曲,刻录在j个光盘中,第j张光盘用了k分钟可以刻录最多的歌曲数量。
f[i-1][j][k]表示不选择第i首歌曲,f[i][j-1][k]表示第i首歌曲刻录在第j-1个光盘中。
f[i-1][j][k-time[i]]表示第i首歌刻录在第j张光盘中,f[i-1][j-1][T]表示第i首歌单独刻录在第j张光盘上,并取前i-1首歌刻录在前j-1张光盘的最优值。
View Code
 1 /*
 2 ID:spcjv51
 3 PROG:rockers
 4 LANG:C
 5 */
 6 #include<stdio.h>
 7 #include<string.h>
 8 #define MAXN 25
 9 int max(int a,int b)
10 {
11     return a>b?a:b;
12 }
13 int main(void)
14 {
15     freopen("rockers.in","r",stdin);
16     freopen("rockers.out","w",stdout);
17     int f[MAXN][MAXN][MAXN],time[MAXN];
18     int i,j,k,t,n,m;
19     scanf("%d%d%d",&n,&t,&m);
20     for(i=1;i<=n;i++)
21     scanf("%d",&time[i]);
22     memset(f,0,sizeof(f));
23     for(i=1;i<=n;i++)
24     for(j=1;j<=m;j++)
25     for(k=0;k<=t;k++)
26     if(k<time[i])
27     f[i][j][k]=max(f[i-1][j][k],f[i][j-1][k]);
28     else
29     f[i][j][k]=max(f[i-1][j][k-time[i]]+1,f[i-1][j-1][t]+1);
30     printf("%d\n",f[n][m][t]);
31     return 0;
32 }

 






posted on 2013-03-15 00:35  仗剑奔走天涯  阅读(212)  评论(0编辑  收藏  举报

导航