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 24 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
思路:枚举所有状态
/*ID:nealgav1LANG:C++PROG:rockers*/#include<fstream>#include<cstring>using namespace std;ifstream cin("rockers.in");ofstream cout("rockers.out");const int mm=33;class node{ public:int t,c; node(){t=c=0;}}dp[mm][mm];int n,t,m;int s[mm];int main(){ while(cin>>n>>t>>m) { int ans=0; for(int i=0;i<n;i++) cin>>s[i]; int z=1<<n; int tt,num,za; for(int i=0;i<z;i++) { tt=t;num=m-1;bool flag=0;za=0; for(int j=0;j<n&&!flag;j++) { if(i&(1<<j)) { ++za; if(tt-s[j]>=0)tt-=s[j]; else if(num) { --num;tt=t-s[j]; if(tt<0)flag=1; } else flag=1; } } if(!flag&&za>ans)ans=za; } cout<<ans<<"\n"; }}DP 背包
/*ID:nealgav1LANG:C++PROG:rockers*/#include<fstream>#include<cstring>using namespace std;ifstream cin("rockers.in");ofstream cout("rockers.out");const int mm=110;int dp[mm][mm],tt[mm],ma[mm];int n,t,m;int main(){ while(cin>>n>>t>>m) { memset(dp,0,sizeof(dp)); memset(ma,0,sizeof(ma)); for(int i=0;i<n;i++)cin>>tt[i]; for(int i=0;i<n;i++) { for(int j=m;j>=1;j--) { dp[j][0]=ma[j-1];///ma[j-1]代表j-1个盘最多装的歌曲数,后面更新第j个盘 for(int k=t;k>=tt[i];--k)///背包,把第i首歌放入背包 if(dp[j][k]<dp[j][k-tt[i]]+1) { dp[j][k]=dp[j][k-tt[i]]+1; ma[j]=ma[j]>dp[j][k]?ma[j]:dp[j][k]; } } } cout<<ma[m]<<"\n"; }}Test 1: TEST OK [0.000 secs, 3404 KB] Test 2: TEST OK [0.000 secs, 3404 KB] Test 3: TEST OK [0.000 secs, 3404 KB] Test 4: TEST OK [0.000 secs, 3404 KB] Test 5: TEST OK [0.000 secs, 3404 KB] Test 6: TEST OK [0.000 secs, 3404 KB] Test 7: TEST OK [0.000 secs, 3404 KB] Test 8: TEST OK [0.000 secs, 3404 KB] Test 9: TEST OK [0.000 secs, 3404 KB] Test 10: TEST OK [0.000 secs, 3404 KB] Test 11: TEST OK [0.000 secs, 3404 KB] Test 12: TEST OK [0.000 secs, 3404 KB]
USER: Neal Gavin Gavin [nealgav1]TASK: rockersLANG: C++Compiling...Compile: OKExecuting... Test 1: TEST OK [0.000 secs, 3364 KB] Test 2: TEST OK [0.000 secs, 3364 KB] Test 3: TEST OK [0.000 secs, 3364 KB] Test 4: TEST OK [0.000 secs, 3364 KB] Test 5: TEST OK [0.000 secs, 3364 KB] Test 6: TEST OK [0.000 secs, 3364 KB] Test 7: TEST OK [0.032 secs, 3364 KB] Test 8: TEST OK [0.162 secs, 3364 KB] Test 9: TEST OK [0.032 secs, 3364 KB] Test 10: TEST OK [0.000 secs, 3364 KB] Test 11: TEST OK [0.151 secs, 3364 KB] Test 12: TEST OK [0.162 secs, 3364 KB]All tests OK.
YOUR PROGRAM ('rockers') WORKED FIRST TIME! That's fantastic -- and a rare thing. Please accept these special automated congratulations.
Here are the test data inputs:
------- test 1 ----4 5 24 2 4 3------- test 2 ----1 1 56------- test 3 ----10 5 55 3 5 3 5 3 5 3 5 2------- test 4 ----10 10 99 7 8 6 10 9 8 6 5 9------- test 5 ----9 15 415 7 8 6 9 5 10 4 11------- test 6 ----15 10 13 6 7 9 6 8 6 7 5 8 10 7 6 3 4------- test 7 ----20 20 210 15 19 18 11 15 14 16 12 14 15 10 10 16 14 16 14 15 16 10------- test 8 ----20 20 1018 15 16 10 2 20 14 17 3 7 16 15 18 16 20 16 13 9 4 16------- test 9 ----18 10 64 9 6 3 9 7 6 9 4 1 10 9 5 8 5 4 7 6------- test 10 ----10 10 208 3 6 4 10 8 2 9 5 10------- test 11 ----20 20 54 9 2 19 5 3 10 15 18 4 3 9 14 17 1 20 15 19 12 6------- test 12 ----20 20 1019 15 1 5 6 19 15 18 13 19 18 5 3 6 2 6 19 13 15 16
Keep up the good work!
Thanks for your submission!
Raucous Rockers Brian Jacokes
This is a pretty straight-forward dynamic programming problem. The factors that determine whether we can put a song on a CD are:
- The length used up on the CD so far
- The length of the current song
- The last song that we put on the CD (because of the date restriction)
Therefore, we create an matrix called "dp", with dp[a][b][c] being the most number of songs that we can put on the first 'a' CDs, with 'b' minutes already used up on the 'a'th CD, and with 'c' being the last song that we put on CD 'a'. We initialize the matrix to be all zeroes, and then we cycle through it as follows:
- We traverse the CDs in ascending order to satisfy the date requirement
- We go through the number of minutes used in ascending order, so that we have had a chance to put on a song earlier in the CD before we try to put songs on at a later time
- We go through the last song used in ascending order (although this order doesn't really matter)
- We go through the new songs in ascending order, making sure to start with songs that were dated after the last song
If the new song that we want to include in the set will fit on the current CD, there is no reason to put it on the next CD, so we check the matrix and see if adding it to the current set of songs will be better than the value already stored in the matrix. Otherwise, we check to see if it would be beneficial to put the song on the next CD. As a time-saver, each time we check a current value in the matrix to see what other songs we can put on the CD, we also check and see if this value is better than the most number of CDs that we have currently been able to fit in the set, so that we don't need to do this at the end. Finally, we output this best number, which will be the most number of CDs that we can fit in the set.
#include <stdio.h>#define MAX 25int dp[MAX][MAX][MAX], length[MAX];int main (){ FILE *in = fopen ("rockers.in", "r"); FILE *out = fopen ("rockers.out", "w"); int a, b, c, d, best, numsongs, cdlength, numcds; fscanf (in, "%d%d%d", &numsongs, &cdlength, &numcds); for (a = 1; a <= numsongs; a++) fscanf (in, "%d", &length[a]); best = 0; for (a = 0; a < numcds; a++)/* current cd */ for (b = 0; b <= cdlength; b++) /* number of minutes used */ for (c = 0; c <= numsongs; c++) { /* last song */ for (d = c + 1; d <= numsongs; d++) { /* new song */ if (b + length[d] <= cdlength) { if (dp[a][b][c] + 1 > dp[a][b + length[d]][d]) dp[a][b + length[d]][d] = dp[a][b][c] + 1; } else { if (dp[a][b][c] + 1 > dp[a + 1][length[d]][d]) dp[a + 1][length[d]][d] = dp[a][b][c] + 1; } } if (dp[a][b][c] > best) best = dp[a][b][c]; } fprintf (out, "%d\n", best); return 0;}