01揹包問題

2021-10-04 13:54:47 字數 2298 閱讀 1205

題目

有n個重量和價值為wi,vi的物品,從這些物品中挑選出總重量不超過m的物品,求所有可選方案中價值總和的最大值。

1<=n<=100

1<=wi,vi<=100

1<=w<=10000

輸入:n=4

(w,v)=,,,}

w=5輸出:

7(選擇0,1,3號物品)

//和子集、全排列很像 ,選還是不選 

//用dfs解決

#include

using

namespace std;

//全域性不需要傳參

int w=

;//重量表

int v=

;//**表

int n=4;

int w=5;

int rec[5]

[6];

intdfs

(int i,

int ww)

//從i號物品開始選 ,ww為還可以裝物品重量

else

}int

main()

//出現了重疊子問題

//解決方法:記憶形遞迴,帶備忘錄

//rec增加速度很多

改進:增加記憶化搜尋,加快搜尋速度

int

dfs1

(int i,

int ww)

//從i號物品開始選 ,ww為還可以裝物品重量

else

//2.計算之後做儲存

rec[i]

[ww]

=ans;

return ans;

}

用excel找規律(dp問題要理解**),演算法根據填表邏輯寫;

找出變化的量:容量變化、物品範圍變化、**變化;

兩個自變數(包的容量,物品選哪些),乙個因變數(**)

畫出二維表

(w,v)

物品編號(當前編號以及之前的範圍)01

2345

(2,3)00

0333

3(1,2)10

2=max(要:2+0,不要:0)

3=max(要:2+0,不要:3)

5=max(2+3,3)

5=max(2+3,3)

5=max(2+3,3)

(3,4)20

235=(4+0,5)

6=(4+2,5)

7=(4+3,3)

(2,2)30

23=(2+0,3)

5=(2+3,5)

6=(2+3,6)

7=(2+5,7)

最右下角的單元格即為所求

從歷史資料處理得出結果 :

我不要這個物品:找上方的單元格

要的話:本物品**+減去當前物品容量的上一行單元格對應的**

根據**寫出演算法如下:

intdp(

)else

}//其他行

for(

int i=

1;i)else}}

return dp[n-1]

[w];

}//遞迴要等子問題結果

//dp不用等,直接用已有問題

intmain()

#include

#include

#include

#include

#include

using

namespace std;

intmax

(int a,

int b)

int f[

1001][

1001];

intmain()

for(

int i=

1;i<=n;i++

)memset

(f,0

,sizeof

(f))

;//把f陣列清零

//和上述演算法不同,邊界是從第一列考慮的

for(

int i=

1;i<=n;i++)}

cout<[v]<}return0;

}

小建議:希望把用dp演算法解決的問題的陣列名都改為dp

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