Ordering problem (classic 0-1 backpack)

Posted by mbh23 on Sat, 05 Mar 2022 09:09:04 +0100

subject

describe

Peking University network laboratory often needs to order takeout for activities, but the maximum amount of reimbursement for each order is C yuan. There are N kinds of dishes to order. After ordering for a long time, the network laboratory has a quantitative evaluation score for each dish i (indicating the palatability of the dish), which is Vi and the price of each dish is Pi. Ask how to choose various dishes, So that the total evaluation score of the dishes ordered can be maximized within the reimbursement limit. Note: due to the need for nutritional diversity, each dish can only be ordered once.

Enter Description:

The first line of input has two integers C (1 < = C < = 1000) and n (1 < = n < = 100). C represents the total amount that can be reimbursed, and N > represents the number of dishes that can be ordered. The next N lines include two integers between 1 and 100 (including 1 and 100), representing the > price of the dish and the evaluation score of the dish respectively.

Output Description:

The output includes only one line, which contains only an integer, indicating the maximum evaluation score of the dishes ordered within the reimbursement limit.

Input:

90 4
20 25
30 20
40 50
10 18
40 2
25 30
10 8

Output:

95
38

 

analysis

The 0-1 knapsack problem wants to be abstract, but it is really simple compared with the longest increasing subsequence in front

(I want to record a video and analyze it carefully later ~ don't worry)

 

 

Answer (time O(n*m), space O(n*m))

(drift past ~ defeat niuke.com 3%hhh~)

/*
-------------------------------------------------
   Author:       wry
   date:         2022/3/5 14:54
   Description:  0-1bag
-------------------------------------------------
*/

#include <bits/stdc++.h>

using namespace std;

const int MAXN = 1000+10;
int price[MAXN][MAXN];    //Total value
int weight[MAXN];
int value[MAXN];

int main() {
    int n,m;    //n Indicates the number of items m Indicates the maximum capacity of the backpack
    while (cin >> m >> n) {
        memset(price,0, sizeof(price));
        for (int i=1;i<=n;i++) {
            cin >> weight[i] >> value[i];
        }
        for (int i=1;i<=n;i++) {
            for (int j=1;j<=m;j++) {
                if (j<weight[i]) {
                    price[i][j] = price[i-1][j];
                }
                else {
                    price[i][j] = max(price[i-1][j-weight[i]]+value[i],price[i-1][j]);    //Judge whether it is sacrificing space i Is the total value of the goods high or not i What is the capacity of the backpack j High value of
                }
            }
        }
        cout << price[n][m] << endl;
    }
    return 0;
}

 

Optimization code (time O(n*m), space O(m))

(the optimization is very ingenious, because in the above code, the price value of each line only depends on the value of the previous line (max(price[i-1][j-weight[i]]+value[i],price[i-1][j]). It can be clearly seen that the I line depends on the i-1 line. Therefore, the optimization scheme is to no longer use the two-dimensional array, only use the one-dimensional array, and update from back to front every time, In this way, there will be no overwrite error! I can only say - wonderful ~ (more than 80%hhhhhh ~)

/*
-------------------------------------------------
   Author:       wry
   date:         2022/3/5 14:54
   Description:  0-1bag
-------------------------------------------------
*/

#include <bits/stdc++.h>

using namespace std;

const int MAXN = 1000+10;
int price[MAXN];    //Total value(Update from back to front)
int weight[MAXN];
int value[MAXN];

int main() {
    int n,m;    //n Indicates the number of items m Indicates the maximum capacity of the backpack
    while (cin >> m >> n) {
        memset(price,0, sizeof(price));
        for (int i=1;i<=n;i++) {
            cin >> weight[i] >> value[i];
        }
        for (int i=1;i<=n;i++) {
            for (int j=m;j>=1;j--) {    //Update from back to front every time
                if (j<weight[i]) {
                    price[j] = price[j];
                }
                else {
                    price[j] = max(price[j-weight[i]]+value[i],price[j]);    //Judge whether it is sacrificing space i Is the total value of the goods high or not i What is the capacity of the backpack j High value of
                }
            }
        }
        cout << price[m] << endl;
    }
    return 0;
}

 

Topics: Algorithm Dynamic Programming