样例输入:
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;
}