Watch The Movie
题意:在N张光盘中选出M张光盘,使得光盘播放时间总和在不超过L的前提下价值最大;
如果题目改为N张光盘中选出M张,使其价值最大:dp[j]=max(dp[j], dp[j-1]+v[i]);
如果改为N张光盘中选出若干张,使其在播放时间总和不超过L的前提下价值最大:dp[j]=max(dp[j], dp[j-t[i]]+v[i]);
上面两个改变都是01背包,现在两种问法合到一起还是01背包,两个状态转移方程合并:dp[k][j]=max(dp[k][j], dp[k-1][j-t[i]]+v[i]);
注意一定要选满M张光盘,所以初始化为-1;
#include <bits/stdc++.h>
using namespace std;
int dp[110][1010], t[110], v[110];
int main(){
int T;
scanf("%d", &T);
while(T--){
int N, M, L;
scanf("%d%d%d", &N, &M, &L);
memset(dp, -1, sizeof(dp));
for(int i=1; i<=N; i++){
scanf("%d%d", &t[i], &v[i]);
}
for(int i=0; i<=L; i++) dp[0][i]=0;
for(int i=1; i<=N; i++){
for(int k=M; k>0; k--){
for(int j=L; j>=t[i]; j--){
if(dp[k-1][j-t[i]]==-1) continue;
dp[k][j]=max(dp[k][j], dp[k-1][j-t[i]]+v[i]);
}
}
}
if(dp[M][L]==-1) dp[M][L]=0;
printf("%d\n", dp[M][L]);
}
return 0;
}