0-1背包问题之回溯法。
问题:
我们有一个背包,背包总的承载重量是Wkg,一共有n个物品,每个物品重量不等且不可分割。我们期望选择几件物品装载到背包中,在不超过背包所能装载的重量个前提下,如何让背包里面的总重量最大?
承载重量设定为100, a数组是每个物品的重量。
代码:
1 #include <iostream> 2 3 int a[] = {11,3,14,5,93, 19, 9,17, 110, 23}; 4 5 int limit_w = 100; 6 7 int max_w = -1; 8 9 void f1(int i, int cw, int items[], int n, int limit_w) 10 { 11 if(i == n || cw == limit_w) 12 { 13 if(cw > max_w) max_w = cw; 14 return; 15 } 16 17 f1(i + 1, cw, items, n,limit_w); 18 19 if(cw + items[i] <= limit_w) 20 { 21 f1(i + 1, cw + items[i], items, n, limit_w); 22 } 23 } 24 25 void f2(int i, int cw, int items[], int n, int limit_w) 26 { 27 if(i == n || cw == limit_w) 28 { 29 if(cw > max_w) max_w = cw; 30 return; 31 } 32 33 if(cw + items[i] <= limit_w) 34 { 35 f1(i + 1, cw + items[i], items, n, limit_w); 36 } 37 38 f1(i + 1, cw, items, n,limit_w); 39 } 40 41 42 int main() 43 { 44 f1(0, 0, a, 10, limit_w); 45 46 std::cout << "f1; max_w = " << max_w << std::endl; 47 48 max_w = 0; 49 50 f2(0, 0, a, 10, limit_w); 51 52 std::cout << "f2; max_w = " << max_w << std::endl; 53 }
函数f2较好理解一点,33行的判断相当于剪枝操作,33行的代码意思为,如果当前的总重量小于限制值,则将当前items中的值加到累加值中,如果走到最后n == i 的时候,发现这条路走不通,则会执行到底38行,不累加当前值,而是直接进行下一次的函数调用。 等到整个f2函数递归完成之后,max_w就是背包所放的物品的总重量个最大值。