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;
}

猜你喜欢

转载自blog.csdn.net/u011321546/article/details/82492646