【ACWing】423. Collecting Medicine

Subject address:

https://www.acwing.com/problem/content/425/

Chenchen is a gifted child, and his dream is to become the greatest physician in the world. For this reason, he wanted to worship the most prestigious physician nearby as his teacher. In order to judge his aptitude, the doctor presented him with a difficult problem. The doctor took him to a cave full of herbs and said to him: "My 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 to him. You can gather some herbs during this period of time. If you are a smart kid, you should be able to maximize the total value of the herbs you gather. "If you are Chenchen, you can complete this task. ?

Input format:
The first line of the input file has two integers TTT andMMM , separated by a space,TTT represents the total time that can be used to gather the medicine,MMM represents the number of herbs in the cave. NextMMEach line of M includes two in1 11 to100 100Between 1 0 0 (including1 11 and100 1001 0 0 ), indicating the time of picking a certain herb and the value of this herb respectively.

Output format: The
output file includes one line. This line only contains an integer, which represents the maximum total value of herbs that can be collected within a specified time.

Data range:
1 ≤ T ≤ 1000 1≤T ≤10001T1000
1 ≤ M ≤ 100 1≤M≤100 1M100

This is a 0 − 1 0-101 The knapsack problem, the classic approach is dynamic programming, letf [i] [j] f[i][j]f [ i ] [ j ] is only before pickingiii herbs and no more thanjjIn the case of j , the maximum value that can be obtained. Then you can follow theiiTo classify i herbs, there are: f [i] [j] = max ⁡ {f [i − 1] [j], f [i − 1] [j − w [i]] + v [i]} f [i][j]=\max\{f[i-1][j],f[i-1][jw[i]]+v[i]\}f[i][j]=max{ f[i1][j],f[i1][jw[i]]+v [ i ] } wherewww represents picking time,vvv stands for value. code show as below:

#include <iostream>
using namespace std;

const int N = 1010, M = 110;
int f[M][N];
int w[M], v[M];

int main() {
    
    
    int n, m;
    cin >> n >> m;
    for (int i = 1; i <= m; i++) cin >> w[i] >> v[i];

    for (int i = 1; i <= m; i++)
        for (int j = 0; j <= n; j++) {
    
    
            f[i][j] = f[i - 1][j];
            if (j >= w[i]) f[i][j] = max(f[i][j], f[i - 1][j - w[i]] + v[i]);
        }
            
    cout << f[m][n] << endl;

    return 0;
}

Time and space complexity O (TM) O (TM)O ( T M )

Space optimization can be considered, and each row is traversed from large to small. code show as below:

#include <iostream>
using namespace std;

const int N = 1010, M = 110;
int f[N];
int w[M], v[M];

int main() {
    
    
    int n, m;
    cin >> n >> m;

    for (int i = 1; i <= m; i++) cin >> w[i] >> v[i];

    for (int i = 1; i <= m; i++)
        for (int j = n; j >= w[i]; j--)
            f[j] = max(f[j], f[j - w[i]] + v[i]);
            
    cout << f[n] << endl;

    return 0;
}

Time complexity is constant, space O (T) O (T)O(T)

Guess you like

Origin blog.csdn.net/qq_46105170/article/details/114242997