我发现了为2个背包的背包算法提供伪代码的线程。我试过用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。对于伪代码错误的任何解释,我将不胜感激。
我没有做太多更新,因为有些人在理解输入格式方面存在问题:
您使用的算法似乎不正确,因为它只会考虑对象恰好适合两个麻袋的情况。我对您的代码进行了以下更改,并且现在可以正常运行:
#include <algorithm> using std::max; int max3(int a, int b, int c) { return max(a, max(b, c)); }
和
for (int w1 = s1; w1 >= 0; w1--) { for (int w2 = s2; w2 >= 0; w2--) { if (w1 >= weight && w2 >= weight) // either sack has room { knapsack[w1][w2] = max3( 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 ); } else if (w1 >= weight) // only sack one has room { knapsack[w1][w2] = max( knapsack[w1][w2], // we have best option knapsack[w1 - weight][w2] + gain // put into sack one ); } else if (w2 >= weight) // only sack two has room { knapsack[w1][w2] = max( knapsack[w1][w2], // we have best option knapsack[w1][w2 - weight] + gain // put into sack two ); } } }