RQNOJ 329 刘翔!加油!:01背包

题目链接: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 }
原文地址:https://www.cnblogs.com/Leohh/p/7460948.html