RQNOJ 95 多多看DVD(加强版):01背包
题目链接:https://www.rqnoj.cn/problem/95
题意:
叔叔要陪多多看动画片。
有n张DVD可以买,第i张碟的打分为w[i],播放时间为t[i]。
爷爷规定他们只能在一定的时间段L看完。
多多让叔叔惯的特别任性,只要他看到有几张就一定会看完。
买碟的地方只买给顾客m(m<n)张碟,不会多也不会少。
在N张碟中只买M张而且在规定时间看完,问你最高的总价值。
题解:
表示状态:
dp[i][j][k] = max value
i:考虑到第i个DVD
j:已经选了j张碟
k:当前的总播放时间
找出答案:
max dp[n][m][0 to L]
所有碟都考虑完,正好选了m张。
如何转移:
now: dp[i][j][k]
dp[i+1][j][k] = max dp[i][j][k] (不选)
dp[i+1][j+1][k+t[i]] = max dp[i][j][k] + w[i] (选)
边界条件:
dp[0][0][0] = 0
others = -1
AC Code:
1 // state expression: 2 // dp[i][j][k] = max value 3 // i: considering ith DVD 4 // j: j DVDs is selected 5 // k: cost time 6 // 7 // find the answer: 8 // max dp[n][m][0 to l] 9 // 10 // transferring: 11 // now: dp[i][j][k] 12 // dp[i+1][j][k] = max dp[i][j][k] 13 // dp[i+1][j+1][k+t[i]] = max dp[i][j][k] + w[i] 14 // 15 // boundary: 16 // dp[0][0][0] = 0 17 // others = -1 18 #include <iostream> 19 #include <stdio.h> 20 #include <string.h> 21 #define MAX_N 105 22 #define MAX_M 105 23 #define MAX_L 1005 24 25 using namespace std; 26 27 int n,m,l; 28 int ans; 29 int t[MAX_N]; 30 int w[MAX_N]; 31 int dp[MAX_N][MAX_M][MAX_L]; 32 33 void read() 34 { 35 cin>>n>>m>>l; 36 for(int i=0;i<n;i++) 37 { 38 cin>>t[i]>>w[i]; 39 } 40 } 41 42 void solve() 43 { 44 memset(dp,-1,sizeof(dp)); 45 dp[0][0][0]=0; 46 for(int i=0;i<n;i++) 47 { 48 for(int j=0;j<=m;j++) 49 { 50 for(int k=0;k<=l;k++) 51 { 52 if(dp[i][j][k]!=-1) 53 { 54 dp[i+1][j][k]=max(dp[i+1][j][k],dp[i][j][k]); 55 if(j+1<=m && k+t[i]<=l) 56 { 57 dp[i+1][j+1][k+t[i]]=max(dp[i+1][j+1][k+t[i]],dp[i][j][k]+w[i]); 58 } 59 } 60 } 61 } 62 } 63 ans=0; 64 for(int i=0;i<=l;i++) 65 { 66 ans=max(ans,dp[n][m][i]); 67 } 68 } 69 70 void print() 71 { 72 cout<<ans<<endl; 73 } 74 75 int main() 76 { 77 read(); 78 solve(); 79 print(); 80 }