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就是背包所放的物品的总重量个最大值。

 

posted on 2020-08-01 19:13  周伯通789  阅读(106)  评论(0编辑  收藏  举报