zoukankan      html  css  js  c++  java
  • USACO3.4.4Raucous 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 }





  • 相关阅读:
    Codeforces Round #629 (Div. 3) (A ~ F)
    st表
    Educational Codeforces Round 81 (Rated for Div. 2)
    hihocoder#1996 : 01匹配
    P2056 [ZJOI2007]捉迷藏
    P2495 [SDOI2011]消耗战
    GUETOJ1335
    优先队列重载比较运算
    CCF认证201909-4 推荐系统
    P3178 [HAOI2015]树上操作
  • 原文地址:https://www.cnblogs.com/zjbztianya/p/2960650.html
Copyright © 2011-2022 走看看