我发现thread提供了两个背包的0/1背包算法伪代码。 我尝试用C++实现它,但结果并不如预期。以下是代码:
#include <cstdio>
#define MAX_W1 501
#define MAX_W2 501
int maximum(int a, int b, int c) {
int max = a>b?a:b;
return c>max?c:max;
}
int knapsack[MAX_W1][MAX_W2] = {0};
int main() {
int n, s1, s2, gain, weight; // items, sack1, sack2, gain, cost
scanf("%d %d %d", &n, &s1, &s2);
// filing knapsack
for (int i = 0; i < n; i++) {
scanf("%d %d", &gain, &weight);
for (int w1 = s1; w1 >= weight; w1--) {
for (int w2 = s2; w2 >= weight; w2--) {
knapsack[w1][w2] = maximum(
knapsack[w1][w2], // we have best option
knapsack[w1 - weight][w2] + gain, // put into sack one
knapsack[w1][w2 - weight] + gain // put into sack two
);
}
}
}
int result = 0;
// searching for result
for (int i = 0; i <= s1; i++) {
for (int j = 0; j <= s2; j++) {
if (knapsack[i][j] > result) {
result = knapsack[i][j];
}
}
}
printf("%d\n", result);
return 0;
}
例如,对于以下输入:
5 4 3
6 2
3 2
4 1
2 1
1 1
我有输出:
13
显然是错误的,因为我可以将所有物品(1,2装入第一个袋子,其余装入第二个袋子),总和为16。如果我有伪代码错误,我会非常感激任何解释。
我进行了一些更新,因为有些人不理解输入格式:
1. 第一行包含3个数字,分别为物品数量、背包一的容量和背包二的容量。 2. 然后有n行,每行包含两个数字:第i个物品的收益和成本。 3. 假设背包大小不能超过500。