數據結構學習筆記10(北大公開課)目錄
解決問題的策略
一、知識概覽
本章介紹了動態案例分析——博物館大盜問題。分別用動態規劃和遞歸法求解。最後對遞歸進行小結。
二、博物館大盜問題
2.1 動態規劃解法
# #博物館大盜問題
# ##動態規劃解法
# #寶物的重量和價值
tr=[None,{'w':2,'v':3},{'w':3,'v':4},
# {'w':4,'v':8},{'w':5,'v':8},
# {'w':9,'v':10}]
# #大盜最大承重
max_w=20
# #初始化二維表格m[(i,w)]
# #表示前i個寶物中,最大重量w的組合,所得到的最大價值
# #當i什麼都不取,或w上限爲0,價值均爲0
m={(i,w):0 for i in range(len(tr))#len(tr)是6
for w in range(max_w+1)}
# #逐個填寫二維表格
for i in range(1,len(tr)):
for w in range(1,max_w+1):
if tr[i]['w']>w:#裝不下第i個寶物
m[(i,w)]=m[(i-1,w)]#不裝第i個寶物
else:
m[(i, w)] =max(
m[(i - 1, w)],
m[(i-1,w-tr[i]['w'])]+tr[i]['v'])
# #輸出結果
print(m[(len(tr)-1,max_w)])
輸出
29
2.2 遞歸解法
#遞歸解法
#寶物的重量和價值,元組的集和
tr={(2,3),(3,4),(4,8),(5,8),(9,10)}
max_w=20
#初始化記憶化表格m
#key是(寶物組合,最大重量),value是最大價值
m={}
def thief(tr,w):
if tr==set() or w==0:
m[tuple(tr),w]=0#tuple是key的要求
return 0#基本結束條件
elif (tuple(tr),w) in m:
return m[tuple(tr),w]
else:
vmax=0
for t in tr:
if t[0]<=w:
#逐個從集合中去掉某個寶物,遞歸調用
#選出所有價值中最大值
v=thief(tr-{t},w-t[0])+t[1]
vmax=max(vmax,v)
m[tuple(tr),w]=vmax
return vmax
print(thief(tr,max_w))
輸出
29