假設一共有n件物品,第 i 件物品的價值為 vi ,重量為wi,乙個小偷有乙個最多只能裝下重量為w的揹包,在總量不超過w的情況下讓總值盡量高。求最大總價值。
n, w = 4, 5
w = [2, 1, 3, 2]
v = [3, 2, 4, 2]
# 解一
def dfs(w:int, v:int, i:int, n:int, w:int) -> int:
""":param i: 物品號碼
:return:
"""if w <= 0: return 0
if i == n: return 0
# 不選擇當前物品
v2 = dfs(w, v, i+1, n, w)
# 選擇當前物品
if w >= w[i]:
v1 = v[i] + dfs(w, v, i+1, n, w-w[i])
return max(v1, v2)
return v2
# 解二
def dfs(w:int, v:int, i:int, n:int, w:int, res:list) -> int:
"""帶記憶的遞迴
:param i: 物品號碼
:return:
"""if w <= 0: return 0
if i == n: return 0
# 查詢
if res[i][w] is not none:
return res[i][w]
# 不選擇當前物品
v2 = dfs(w, v, i+1, n, w, res)
# 選擇當前物品
if w >= w[i]:
v1 = v[i] + dfs(w, v, i+1, n, w-w[i], res)
ans = max(v1, v2)
else:
ans = v2
# 記錄
res[i][w] = ans
return ans
res = [[none]*(w+1) for _ in range(n)]
解三
# 初始化dp第一行
for i in range(w+1):
dp[0][i] = v[0] if i >= w[0] else 0
# i表示物品編號
for i in range(1, n):
# j表示揹包容量
for j in range(1, w+1):
va = v[i]+ dp[i-1][j-w[i]] if j >= w[i] else dp[i-1][j]
dp[i][j] = max(dp[i-1][j], va)
return dp[-1][-1]
解題報告 01揹包
這應該是最基礎的揹包問題了,但正因為他的基礎,他的思想會被用在很多dp題中,所以這裡有必要對他剖析一下。我們應該掌握的方法有兩種 1 二維陣列。2 滾動陣列。後面那個一看就要高階一些,但是確實對動歸沒有太大的幫助,所以大家一定要把第一種方法學好!第二種方法我不做解釋,只會黏貼 大家認真腦補一下應該也...
揹包 01揹包
01揹包 有n種物品與承重為m的揹包。每種物品只有一件,每個物品都有對應的重量weight i 與價值value i 求解如何裝包使得價值最大。dp i,v 表示前i個物體 包括第i個 面對容量為v的揹包的最大價值,c i 代表物體i的重量,w i 代表物體i的價值 如果第i個物體不放入揹包,則揹包...
0 1揹包問題(動態規劃) 解題報告
利用動態規劃,以自底向上的方式解各子問題。解題思路 此問題可轉化為 給定c 0,wi 0,vi 0,1 i n,要求找出一 個n元0 1向量 x1,x2,xn xi 1 i n,使得 wixi c,而且 vixi達到最大。因此,0 1揹包是乙個特 殊的整數規劃問題 max vixi s.t.wixi...