题目链接:https://www.rqnoj.cn/problem/329
题意:
刘翔有n封信,每封信都有自己的欣赏价值value[i]、消耗时间time[i]、消耗体力h[i]、和得到的鼓舞w[i]。
观看信件必须按照价值递增(大于)的顺序观看,不一定需要全看。
可是,刘翔在伤病中,时间和体力分别为t,m,同时看完之后体力不能为0。
问你受到的鼓舞最大为多少。
题解:
这道题里value[i]真的没有用。。。
表示状态:
dp[i][j][k] = max encouraging
i:考虑到第i封信
j:花费的时间
k:花费的体力
找出答案:
ans = max dp[i][j][k] (0<=j<=t, 0<=k<m)
如何转移:
dp[i][j][k] = max(dp[i-1][j][k], dp[i-1][j-c[i]][k-h[i]] + w[i]) (01背包)
边界条件:
set dp = 0
AC Code:
1 // state expression: 2 // dp[i][j][k] = max encouraging 3 // i: ith letter was considered 4 // j: time cost 5 // k: hp cost 6 // 7 // find the answer: 8 // max dp[i][j][k] (0<=j<=t, 0<=k<m) 9 // 10 // transferring: 11 // dp[i][j][k] = max(dp[i-1][j][k], dp[i-1][j-c[i]][k-h[i]] + w[i]) 12 // 13 // boundary: 14 // set dp = 0 15 #include <iostream> 16 #include <stdio.h> 17 #include <string.h> 18 #define MAX_N 105 19 #define MAX_T 105 20 #define MAX_H 105 21 22 using namespace std; 23 24 int n,m,t; 25 int ans; 26 int w[MAX_N]; 27 int c[MAX_N]; 28 int h[MAX_N]; 29 int dp[MAX_N][MAX_T][MAX_H]; 30 31 void read() 32 { 33 cin>>n>>m>>t; 34 int v; 35 for(int i=1;i<=n;i++) 36 { 37 cin>>v>>c[i]>>h[i]>>w[i]; 38 } 39 } 40 41 void solve() 42 { 43 memset(dp,0,sizeof(dp)); 44 ans=0; 45 for(int i=1;i<=n;i++) 46 { 47 for(int j=0;j<=t;j++) 48 { 49 for(int k=0;k<m;k++) 50 { 51 dp[i][j][k]=max(dp[i][j][k],dp[i-1][j][k]); 52 if(j-c[i]>=0 && k-h[i]>=0) 53 { 54 dp[i][j][k]=max(dp[i][j][k],dp[i-1][j-c[i]][k-h[i]]+w[i]); 55 } 56 ans=max(ans,dp[i][j][k]); 57 } 58 } 59 } 60 } 61 62 void print() 63 { 64 cout<<ans<<endl; 65 } 66 67 int main() 68 { 69 read(); 70 solve(); 71 print(); 72 }