Time Limit: 1000MS Memory Limit: 65536K
【Description】 |
【题目描述】 |
New semester is coming, and DuoDuo has to go to school tomorrow. She decides to have fun tonight and will be very busy after tonight. She like watch cartoon very much. So she wants her uncle to buy some movies and watch with her tonight. Her grandfather gave them L minutes to watch the cartoon. After that they have to go to sleep. DuoDuo list N piece of movies from 1 to N. All of them are her favorite, and she wants her uncle buy for her. She give a value Vi (Vi > 0) of the N piece of movies. The higher value a movie gets shows that DuoDuo likes it more. Each movie has a time Ti to play over. If a movie DuoDuo choice to watch she won’t stop until it goes to end. But there is a strange problem, the shop just sell M piece of movies (not less or more then), It is difficult for her uncle to make the decision. How to select M piece of movies from N piece of DVDs that DuoDuo want to get the highest value and the time they cost not more then L. How clever you are! Please help DuoDuo’s uncle. |
新学期即将开始,DuoDuo明天就要去学校了。想了想之后忙碌的生活,她还是决定在今晚找找乐子。DuoDuo十分喜欢欧美动画。因此她希望她叔叔买些回来晚上一起看。她爷爷却给她限定L分钟的时间看动画,之后必须去睡觉。 DuoDuo从1到N列了N部电影。对于她的最爱,统统都想要。她给出了对这N部电影的好感度Vi(Vi > 0)。数值越高,DuoDuo越喜欢。每部电影时长为Ti。DuoDuo一旦开始观看,就势必要看完。 但是奇葩的是,这家商店只出售M部影片(不多不少),这可难坏了她叔叔。如何才能在N部DuoDuo想要的DVDs中挑M部并且在不超过L的时间内收获最多的好感度? 聪明如你!定可助DuoDuo的叔叔一臂之力。 |
【Input】 |
【输入】 |
The first line of the input file contains a single integer t (1 ≤ t ≤ 10), the number of test cases, followed by input data for each test case: The first line is: N(N <= 100),M(M<=N),L(L <= 1000) N: the number of DVD that DuoDuo want buy. M: the number of DVD that the shop can sale. L: the longest time that her grandfather allowed to watch. The second line to N+1 line, each line contain two numbers. The first number is the time of the ith DVD, and the second number is the value of ith DVD that DuoDuo rated. |
输入数据的第一行是一个整数t(1 ≤ t ≤ 10),表示测试用例的数量,随后的每个测试用例: 第一行:N(N <= 100),M(M<=N),L(L <= 1000) N:DuoDuo想买的DVD数量。 M:商店可出售的DVD数量。 L:她爷爷运行的最长观看时间。 第二到N+1行,每行两个数。第一个数字表示第i个DVD的时长,第二个数字表示DuoDuo对其的好感度。 |
【Output】 |
【输出】 |
Contain one number. (It is less then 2^31.) The total value that DuoDuo can get tonight. If DuoDuo can’t watch all of the movies that her uncle had bought for her, please output 0. |
包含一个数字。(小于2^31。) DuoDuo今晚收获的好感度。 如果DuoDuo不能看完她叔叔所买的电影则输出0。 |
【Sample Input - 输入样例】 |
【Sample Output - 输出样例】 |
1 3 2 10 11 100 1 2 9 1 |
3 |
【题解】
二维01背包
(之前为了看(qiang)着(po)爽(zheng)用vector来写,写着写着代码量比预期越来越高,于是默默地放弃了……)
最后的好感度V太大,不过时间T和DVD的数量N都不大,可以用来当坐标轴。
考虑到T或N在某一状态都可能相同,因此T与N都应该成为坐标轴,其值为V。
这么看来就是一个二维的01背包了。 V[T][N]或V[N][T]怎么开都行。
【代码 C++】
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define time 1005 5 #define cdSUM 105 6 int main(){ 7 int ts, i, j, t, v, n, m, tLimt, cd[cdSUM][2], value[time][cdSUM]; 8 scanf("%d", &ts); 9 while (ts--){ 10 memset(value, 0, sizeof(value)); 11 scanf("%d%d%d", &n, &m, &tLimt); 12 while (n--){ 13 scanf("%d%d", &t, &v); 14 for (i = tLimt - 1; i > 0; --i){ 15 for (j = 0; j < m; ++j){ 16 if (value[i][j] && i + t <= tLimt){ 17 value[i + t][j + 1] = std::max(value[i][j] + v, value[i + t][j + 1]); 18 } 19 } 20 } 21 value[t][1] = std::max(v, value[t][1]); 22 } 23 for (i = v = 0; i <= tLimt; ++i) v = std::max(v, value[i][m]); 24 printf("%d\n", v); 25 } 26 return 0; 27 }