1. 程式人生 > >2019美團校招一道程式設計題

2019美團校招一道程式設計題

樣例輸入:

4

20 20 100 60

50 30 80 55

100 60 110 88

5 3 10 6

樣例輸出:

94

 

分析:

經典01揹包問題參考:https://blog.csdn.net/u011321546/article/details/9358253

變相的 01揹包問題,如果每道題只有一種方式,則就是典型的01揹包問題,而此時每道題有兩種解題方式,而且每種解題方式只能選擇一種。

比如樣例輸入為如下:

4

20 20 100 60

50 30 80 55

100 60 110 88

4 3 5 6

如果按照經典揹包演算法,輸出為97,第四題的4 3 5 6兩種解法全部會加到結果中

所以:每次比較兩組,呼叫兩次核心揹包公式,然後再從兩個結果中選出一個:

程式碼如下:

#include <iostream>
#define V 500
using namespace std;
int weight[20 + 1];
int value[20 + 1];
int f1[V + 1];//第一種解法的結果
int f2[V + 1];//第二種解法的結果
int f3[V + 1];//兩種解法的最優結果
int main() {
    int n, m=120;
    cin >> n;
    for (int i = 1; i <= 2*n; i++) {
        cin >> weight[i] >> value[i];
    }
    for (int i = 1; i <= 2*n; i=i+2) {

        for (int j = m; j >= 1; j--) {
            if (weight[i] <= j) {
                f1[j] = f1[j] > f1[j - weight[i]] + value[i] ? f1[j] : f1[j - weight[i]] + value[i];
            }
            if (weight[i+1] <= j) {
                f2[j] = f2[j] > f2[j - weight[i+1]] + value[i+1] ? f2[j] : f2[j - weight[i+1]] + value[i+1];
            }
            f3[j] = f1[j] > f2[j]?f1[j] : f2[j];
        }
    }
    cout  << f3[m] << endl;
}