0 1揹包問題全解析

2021-10-04 19:09:57 字數 3242 閱讀 4179

0-1揹包問題

給定n個重量為w1/w2/w3.../wn,價值為v1/v2/v3.../vn的物品,容量為c的揹包,求這個揹包可以裝下的價值最高的子集,每個物品只能使用一次

w =

//重量v=

// 價值

c = 5 // 容量

#最佳子集為 [2,1,2] 12+10+15 = 37

對每個物品,都有選擇/不選兩個狀態,這樣解空間就可以描述成乙個狀態樹,

可以很像求子集的問題,不同的地方就是,子集的重量和需要小於揹包重量,否則需要剪枝,如2->1->3不滿足報容量,則3不可成為2->1這個子路徑的葉節點,然後統計每乙個子集的價值總和,比較得出最大值即可;

void

backtrack

(vector<

int> w,vector<

int> v,

int c,

int index,

int& res,

int val)

if(c >= w[index]

)backtrack

(w,v,c,index+

1,res,val);}

intmain()

; vector<

int> v =

;int res =

0,c=5;

backtrack

(w,v,c,

0,res,0)

; cout<

return0;

}

因為上述方法會存在很多重複子問題的計算,所以我們可以儲存子問題計算的結果,從而達到剪枝的效果

int

backtrack2

(vector<

int> w,vector<

int> v,

int c,

int index,

int val,vector

int>>

& memo)

if(memo[index]

[c]!=-1

)return memo[index]

[c];

int aa =0;

if(c >= w[index]

) aa =

max(aa,

backtrack2

(w,v,c,index+

1,val,memo));

memo[index]

[c]= aa;

return aa;

}int

main()

; vector<

int> v =

;int res =0;

vector

int>>

memo

(w.size()

,vector<

int>(6

,-1)

);res =

backtrack2

(w,v,5,

0,0,memo)

; cout<

return0;

}

我們可以使用乙個二維陣列dp[n][c+1],表示第幾個物體 在c容量下的價值;

dp[i][j] = max(dp[i-1][j] , dp[i-1][j-w[i] ] + v[i])

表示w[i]i個物體不裝入揹包的話,則直接由上一層價值傳遞,如果w[i]裝入揹包的話,則由dp[i-1][j-w[i]]上一層 減去物體重量時的價值 + 物體本身的價值,取兩者大,**示意圖如下:

| 揹包容量

----------

物體id |

*/

給定乙個僅包含正整數的非空陣列,確定該陣列是否可以分成兩部分,要求兩部分的和相等

[1,2,3,6] -->

[1,2,3],[6]

int

dfs_dp

(vector<

int> w ,

int c)

}for

(auto i:dp)

return dp[n-1]

[c];

}int

main()

; bool flag =

dfs_dp

(v1,6)

; cout<

return0;

}/*0 1 0 0 0 0 0

0 1 0 1 0 0 0

0 1 0 1 1 0 1

0 1 0 1 1 0 1

*/

揹包問題 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...