揹包問題有0-1揹包問題和fraction揹包問題,前者規定每個物品要麼選,要麼不選,而fraction knanpsack允許選取乙個物品的一部分,0-1揹包問題是np難的,而fraction knapsacks的複雜度是o(n*logn), 只需要將單位物品的價值按降序排列,利用貪心策略選取即可得到最優解。
給定乙個揹包,容量為c,有n個物品,重量為n維行向量w,價值為n維行向量v. |v|=|w|=n, n維向量y=[0,1,0….yn]代表物品的選法,其中的沒有元素yi,要麼是0、要麼是1,為零代表選取第i個物品,為0表示不選取第i個物品。 目標函式是:max(sum(vi*yi)), 約束條件是sum(wi*yi) <=c, 其中 1=< i <=n.
揹包問題具有最優子結構,令f(n,c)代表,有n個待選物品,揹包容量為c時的最優解,此時物品選擇向量為y=[y1,y2,…yn], 那麼當yn=1時,y』=[y1, y2, …yn-1],必然為f(n-1, c-wn)的物品選擇向量,當yn=0時,必然為f(n-1,c)的最優物品選擇向量。所以揹包問題可以由動態規劃來求解。
根據上面的分析,我們可以得到如下的遞迴式:
當wn>c時, f(n,c)=f(n-1,c);
當wn<=c時,f(n,c) = max(f(n-1,c), vn+f(n-1, c-wn) );
初始條件為:f(i, 0) = 0; f(0,i) = 0; f(0,0) = 0;
根據上面的分析用遞迴實現的0-1揹包**如下:
1: /*
2: *
5: *email:[email protected]
6: */
7:
8: #include 9: #include 10: using namespace std;
11:
12: int w=;//物品重量陣列
13: int v=;//物品價值陣列
14: int c=5;//揹包容量
15: int y[4]=;//解向量,y[i]=1表示選取物品,y[i]=0表示不選取物品
16:
17:
18: int f(int n, int c)
19:
24: else
25:
37: else
38:
49: else
50:
54:
55: }
56: }
57:
58: }
59:
60: }
61:
62:
63: int main()
64: {
65:
66: int maxvalue = f(4,5);
67: for (int i=0; i<4; i++)
68: {
69: if (y[i]==1)//為1表示相應的物品被選取
70: {
71: cout << "object "<< i+1 << " is selected. " << "it's vaule is " << setw(2)<< v[i] \
72: << " it's weight is"<< setw(2)<
揹包問題 01揹包問題
n個物品,總體積是v,每個物品的體積的vi,每個物品的最大價值是wi,在不超過v的體積下求最大價值 eg揹包容積為 5 物品數量為 4 物品的體積分別為 物品的價值分別為 思路定義乙個二位陣列int f new int n 1 v 1 f i j 就表示在1 i個物品中選取體積小於v的情況的最大價值...
揹包問題 01揹包
有n件物品和乙個容量為v的揹包。第i件物品的重量是c i 價值是w i 求解將哪些物品裝入揹包可使價值總和最大。01揹包中的 01 就是一種物品只有1件,你可以選擇放進去揹包即1,也可以選擇不放入揹包中即0。include include using namespace std const int ...
揹包問題(01揹包)
1085 揹包問題 在n件物品取出若干件放在容量為w的揹包裡,每件物品的體積為w1,w2 wn wi為整數 與之相對應的價值為p1,p2 pn pi為整數 求揹包能夠容納的最大價值。input 第1行,2個整數,n和w中間用空格隔開。n為物品的數量,w為揹包的容量。1 n 100,1 w 10000...