大盜潛入博物館,面前有5件寶物,分別有重量和價值,大盜的揹包僅能負重20公
斤,請問如何選擇寶物,總價值最高?
物品重量價值1
2323
4348
4585
910明確問題以後,我們需要建立動態規劃**
m[(i, w)]:
其中 i
ii 是裝物品的數量 ( 0≤i
≤50\le i\le 5
0≤i≤5 )
,w
ww 是物品的載重 ( 0≤w
≤200\le w\le 20
0≤w≤20)mm
m 則是這些物品的總價值, 也即是我們需要存入的值。
如何填寫動態規劃**呢?
1.i=0(即沒有拿寶物)和w=0(最大載重為20)這兩種情況下,總價值都為0
2.用迴圈對每次拿寶物數量和最大載重值進行查詢填表
import time
# 按標籤逐個匯入寶物的重量和價值
tr =
[none,,
,,,]
# 設定最大容量
max_weight =
20# 建立動態規劃**m[(i,w)]
# i表示取得物品個數
# w表示物品最大限制重量
defgettreasure
(tr, max_weight)
: m =
# 動態規劃填補**
for i in
range(1
,len
(tr)):
for w in
range(1
, max_weight+1)
:# 若當前第i件物品重量超出最大載重,則不裝第i件物品,總價值等於第i-1次總重為w的價值(即撐爆了不加該次的價值)
# 否則飯回 裝或者不裝該次物品 這兩種情況下的最大值
if tr[i]
['w'
]> w:
m[(i, w)
]= m[
(i-1
, w)
]else
: m[
(i, w)]=
max(m[
(i-1
, w)],
m[(i-1
, w-tr[i]
['w'])
]+ tr[i]
['v'])
return m[
(len
(tr)-1
, max_weight)
]t1 = time.process_time(
)print
(gettreasure(tr, max_weight)
)t2 = time.process_time(
)print
('process time:\t'
.format
(t2-t1)
)
結果
# 用元組建立遞迴集合,包含重量和價值
tr =
max_weight =
20# 建立儲存**m
m =# 初始化記憶化**m
# key是(寶物組合,最大重量),value是最大價值
defgettreasure
(tr, w)
:if tr ==
set(
)or w ==0:
m[(tuple
(tr)
, w)]=
0return
0elif
(tuple
(tr)
, w)
in m:
return m[
(tuple
(tr)
, w)
]else
: vmax =
0for t in tr:
if t[0]
<= w:
# 逐個從集合中去掉某個寶物,遞迴呼叫
# 選出所有價值中的最大值
v = gettreasure(tr-
, w-t[0]
)+ t[1]
vmax =
max(v, vmax)
m[(tuple
(tr)
, w)
]= vmax
return vmax
t1 = time.process_time(
)print
(gettreasure(tr, max_weight)
)t2 = time.process_time(
)print
('process time:\t'
.format
(t2-t1)
)
結果 Bill Gates的博物館
最後再說一句。我在老闆那裡看見這句話,忍不住與大家分享 我喜歡在這個地方工作 microsoft 過去有過許多競爭者。還好,我們有很多博物館來收藏它們。microsoft 董事長 bill gates,forbes.com,2004 年 10 月 4 日。shawn msdn online 總編輯 ...
Bill Gates的博物館
最後再說一句。我在老闆那裡看見這句話,忍不住與大家分享 我喜歡在這個地方工作 microsoft 過去有過許多競爭者。還好,我們有很多博物館來收藏它們。microsoft 董事長 bill gates,forbes.com,2004 年 10 月 4 日。shawn msdn online 總編輯 ...
Bill Gates的博物館
最後再說一句。我在老闆那裡看見這句話,忍不住與大家分享 我喜歡在這個地方工作 microsoft 過去有過許多競爭者。還好,我們有很多博物館來收藏它們。microsoft 董事長 bill gates,forbes.com,2004 年 10 月 4 日。shawn msdn online 總編輯 ...