Raucous Rockers
Raucous Rockers |
You just inherited the rights to n previously unreleased songs recorded by the popular group Raucous Rockers. You plan to release a set of m compact disks with a selection of these songs. Each disk can hold a maximum of t 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 will be recorded on the set of disks in the order of the dates they were written.
- The total number of songs included will be maximized.
Input
The input consists of several datasets. The first line of the input indicates the number of datasets, then there is a blank line and the datasets separated by a blank line. Each dataset consists of a line containing the values of n, t and m (integer numbers) followed by a line containing a list of the length of n songs, ordered by the date they were written (Each
is between 1 and t minutes long, both inclusive, and
.)
Output
The output for each dataset consists of one integer indicating the number of songs that, following the above selection criteria will fit on m disks. Print a blank line between consecutive datasets.
Sample Input
2 10 5 3 3, 5, 1, 2, 3, 5, 4, 1, 1, 5 1 1 1 1
Sample Output
6 1
题意:有n首音乐,m个磁盘,磁盘容量都是t,一首音乐不能被分割到两个盘里,问最多能在磁盘里放置多少音乐。要求音乐的放置不能逆序。即下标大的不能放在下标小的前面。
思路:dp[i][j][k]表示第i首音乐,放在第j个磁盘的k位置,这样就看磁盘放不放,如果不放dp[i][j][k] = max(dp[i][j][k], dp[i - 1][j][k]);如果放,如果是放在第一个位置的情况要特殊考虑,因为放在第一个位置的话等于上一张磁盘的最后一个位置dp[i][j][k] = max(dp[i][j][k], dp[i - 1][j - 1][t] + 1);否则为dp[i][j][k] = max(dp[i][j][k], dp[i - 1][j][k - cd[i]] + 1);然后可以利用滚动数组去优化,少掉第一维。
代码:
#include <stdio.h>
#include <string.h>
#define max(a,b) ((a)>(b)?(a):(b))
const int N = 105;
int T, n, t, m, cd, dp[N][N];
int solve() {
memset(dp, 0, sizeof(dp));
for (int i = 1; i <= n; i++) {
scanf("%d%*c", &cd);
for (int j = m; j >= 1; j--) {
for (int k = t; k >= 1; k--) {
if (k < cd) continue;
dp[j][k] = max(dp[j][k], dp[j - 1][t] + 1);
dp[j][k] = max(dp[j][k], dp[j][k - cd] + 1);
}
}
}
return dp[m][t];
}
int main() {
scanf("%d", &T);
while (T--) {
scanf("%d%d%d", &n, &t, &m);
printf("%d\n", solve());
if (T) printf("\n");
}
return 0;
}