HDU 3496 Watch The Movie(看電影)less
Time Limit: 1000MS Memory Limit: 65536Kide
【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.spa
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.code
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.blog
How clever you are! Please help DuoDuo’s uncle.ip |
新學期即將開始,DuoDuo明天就要去學校了。想了想以後忙碌的生活,她仍是決定在今晚找找樂子。DuoDuo十分喜歡歐美動畫。所以她但願她叔叔買些回來晚上一塊兒看。她爺爺卻給她限定L分鐘的時間看動畫,以後必須去睡覺。ci DuoDuo從1到N列了N部電影。對於她的最愛,通通都想要。她給出了對這N部電影的好感度Vi(Vi > 0)。數值越高,DuoDuo越喜歡。每部電影時長爲Ti。DuoDuo一旦開始觀看,就勢必要看完。get
可是奇葩的是,這家商店只出售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 }