1. 程式人生 > 實用技巧 >回溯: 0-1揹包

回溯: 0-1揹包

0-1揹包問題之回溯法。

問題:

我們有一個揹包,揹包總的承載重量是Wkg,一共有n個物品,每個物品重量不等且不可分割。我們期望選擇幾件物品裝載到揹包中,在不超過揹包所能裝載的重量個前提下,如何讓揹包裡面的總重量最大?

承載重量設定為100, items是每個物品的重量,從1還是計數,所以前面補一個0.

程式碼:

 1 #include <iostream>
 2 
 3 int items[] = {0, 11,3,13,4,6,  19, 9,17, 1, 21};
 4 
 5 int limit_w = 100;
 6 
 7 int max_w = 0;
 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, items, 10, limit_w); 45 46 std::cout << "f1; max_w = " << max_w << std::endl; 47 48 max_w = 0; 49 50 f2(0, 0, items, 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就是揹包所放的物品的總重量個最大值。