JakeLin- [ACM Training] Herbal Medicine-DP / 01 Backpack-Solution

Topic description
Chen Chen is a talented child, his dream is to become the greatest physician in the world. For this reason, he wanted to worship the most prestigious physician nearby as a teacher. In order to judge his qualifications, the doctor gave him a problem. The doctor took him to a cave full of herbs and said to him: "Child, there are some different herbs in this cave. It takes some time to pick each plant, and each plant has its own value. I will give it You have a period of time, during this time, you can collect some herbs. If you are a smart child, you should be able to maximize the total value of the herbs you have collected. " 
If you are Chenchen, you can complete this task ?

Input

Enter two integers T (1 <= T <= 1000) and M (1 <= M <= 100) in the first line of input, separated by a space, T represents the total time available for medicine collection, M represents the cave The number of herbs in the field. Each row of the next M lines includes two integers between 1 and 100 (including 1 and 100), respectively representing the time of picking a certain herb and the value of this herb.

Output

Output a line, this line contains only an integer, which represents the maximum total value of herbs that can be harvested within a specified time.

Sample input

70 3
71 100
69 1
1 2

Sample output

3

Original title link: Herbal Medicine

1. The idea of ​​0/1 backpack dynamic programming is:

When I reach this i-th medicine, I have two options :
1. I want to pick it: if I pick it, then the time I have will decrease, and the value I get will increase
2. I do n’t pick it : If I do n’t pick it, then my time will not decrease, the value will not increase, and the value at step i-1 will remain.


Second, we have conventionally designed a DP array int dp[maxn][maxn2];, and its principle is very important:
dp[i][j]what is the value represented? Is the maximum value in this state! What state? It is considering the i-th item (the first i-1 has already been arranged), in such a state that takes time j, the maximum value.
So can we think of it this way: the entire program is actually constructing a dp array, which can summarize the three elements [number of items]-[how much is left]-[how much total value] into one state, and the end point isdp[所有物品][所有时间]


Back to one, continue to analyze two situations:

1. Analyze the i-th item :

Then it is necessary to determine dp [i] [*], at this time cost [i], value [i] represent the cost and time of the ith item

2. Re-analyze the remaining time j :

  • If the remaining time is less than cost [i], then it is definitely not possible to pick it up. There is no time.
  • If I have enough time, then I have to consider:
    • If I pick it, it constitutes a new state, my remaining time reduces cost [i], and the value increases by value [i]: dp [i] [j]-> dp [i-1] [ j-cost [i]] + value [i]
    • If I do n’t pick, I will neither spend time nor increase value, the state dp [i] [j] is the same as dp [i-1] [j]
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn = 100 + 10;
const int maxn2 = 1000 + 10; 
int cost[maxn];
int value[maxn];
int dp[maxn][maxn2];
int main(){
    int n,m;
    cin>>n>>m;
    for(int i=1;i<=m;i++){
        cin>>cost[i]>>value[i];
    }
    for(int i=1;i<=m;i++){  //第i个物品(药)是否放入背包(采它) 
        for(int j=1;j<=n;j++){  // 遍历可能的时间情况 
            if(j>=cost[i]){  //max(采,不采) 
                dp[i][j] = max(dp[i-1][j-cost[i]]+value[i],dp[i-1][j]);
            }else{  //cost[i]:采第i个药要花的时间,如果j不够肯定采不了 
                dp[i][j] = dp[i-1][j];    
            }
        }
    }
    cout<<dp[m][n];
    return 0;
}

 Subsequent optimization, the dp array is removed one dimension, the dimension representing i (i medicines) is less, and the dp array is constructed [from bottom to top] :

#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn = 110;
const int tmaxn = 1010;
int cost[maxn],value[maxn];
int dp[tmaxn];
int main(){
    int t,m;
    cin>>t>>m;
    for(int i=1;i<=m;i++){
        cin>>cost[i]>>value[i];
    }
    for(int i=1;i<=m;i++){
        for(int j=t;j>=cost[i];j--){
            dp[j] = max(dp[j],dp[j-cost[i]]+value[i]);
        }
    }
    cout<<dp[t];
    return 0;
}

 

The above is the use of two DP algorithms to solve the problem of 0/1 backpack. 

Published 20 original articles · won 15 · views 216

Guess you like

Origin blog.csdn.net/qq_37414463/article/details/105386756