01揹包問題

2021-10-05 17:11:49 字數 2588 閱讀 8286

問題描述

給定n個物品和乙個容量為capacity的揹包,物品i的大小為w[i],物品i的價值為v[i]。如何選擇物品裝入揹包,使揹包中物品價值最大?

思路分析:動態規劃

動態規劃陣列:dp[i][j]表示從前i個物品中挑選物品放入容量為j的揹包中所得到的揹包的總價值。

則面對第i個物品,有兩種選擇:放與不放。

①當目前揹包容量大於等於當前物品的大小時,可以放,也可以不放,所以要選擇兩者的最大值。

其中,dp[i-1][j-w[i]]是判斷完前(i-1)個物品後的揹包內的總價值,加上第i個物品的價值v[i],即為當前揹包價值

②當前揹包容量小於當前物品大小時,當前物品一定放不下,所以dp[i][j] = dp[i-1][j]。

狀態轉移方程為:

**實現

①填寫動態規劃表,dp二維陣列初始化為0。

# 填寫動態規劃表

for i in range(1, n + 1):

for j in range(1, capacity + 1):

# 如果揹包容量小於當前物品大小,則不放

if j < w[i]:

dp[i][j] = dp[i - 1][j]

# 反之,可以放也可以不放,取兩者的最優解

else:

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

②回溯找到最優解的情況

填完動態規劃表之後,能夠得到最優解,但是還不知道具體的最優解情況,即要選擇哪些物品,所以要回溯找出最優解的組成。

和填寫動態規劃表相反:

如果dp[i][j] == dp[i-1][j],說明第i個物品放與不放對揹包價值沒有影響,所以回到前一狀態,即dp[i-1][j]的狀態。

如果dp[i][j] != dp[i-1][j]且dp[i][j] = dp[i-1][j-w[i]]+v[i],說明第i個物品放入了揹包中,所以回到dp[i-1][j-w[i]]這一狀態。

直到i==0,回溯到頂端停止。

在回溯過程中,維護乙個res陣列,大小為物品的個數,記錄對應的物品是否放入揹包中。對於放入揹包中的物品,陣列對應位置的值置為1;沒有放入,就置為0。

# 回溯找到最優解情況存放到res陣列中,0:不放;1:放

def find(i, j, res):

if i > 0:

# 沒有放入第i個物品

if dp[i][j] == dp[i - 1][j]:

# 最優解陣列當前位置標記為0

res[i] = 0

# 遞迴

find(i - 1, j, res)

# 放入第i個物品

elif j - w[i] >= 0 and dp[i][j] == dp[i - 1][j - w[i]] + v[i]:

res[i] = 1

find(i - 1, j - w[i], res)

③完整**

w = [0, 2, 3, 4, 5]     # 物品大小

v = [0, 3, 4, 5, 6] # 每個物品對應的價值

n, capacity = 4, 8

# dp[i][j]表示當前揹包容量為j,前i個物品的價值

# 初始化dp陣列為0

dp = [[0 for j in range(capacity + 1)] for i in range(n + 1)]

# 存放最優解情況

res= [0 for i in range(n + 1)]

# 填寫動態規劃表

for i in range(1, n + 1):

for j in range(1, capacity + 1):

# 如果揹包容量小於當前物品大小,則不放

if j < w[i]:

dp[i][j] = dp[i - 1][j]

# 反之,可以放也可以不放,取兩者的最優解

else:

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

# 回溯找到最優解情況存放到res陣列中,0:不放;1:放

def find(i, j, res):

if i > 0:

# 沒有放入第i個物品

if dp[i][j] == dp[i - 1][j]:

# 最優解陣列當前位置標記為0

res[i] = 0

# 遞迴

find(i - 1, j, res)

# 放入第i個物品

elif j - w[i] >= 0 and dp[i][j] == dp[i - 1][j - w[i]] + v[i]:

res[i] = 1

find(i - 1, j - w[i], res)

# 呼叫回溯函式

find(n, capacity, res)

# 輸出物品選擇情況

print(res)

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