递归代码Ⅰ:
w = [0, 2, 3, 4, 5, 9]
v = [0, 3, 4, 8, 8, 10]
max_W = 20
sum = {(i, w1):0 for i in range(len(w))
for w1 in range(max_W+1)}
# python对数据操作的实现很容易
def m(i, W): # 第i个物品怎么放
if i == 0:
sum[(i, W)] = 0
return 0
elif W == 0:
sum[(i, W)] = 0
return 0
elif sum[(i, W)] != 0:
return sum[(i, W)]
elif w[i] > W:
sum[(i, W)] = m(i-1, W)
return sum[(i, W)]
else:
sum[(i, W)] = max(m(i-1, W), v[i] + m(i-1, W-w[i]))
return sum[(i, W)]
for i in range(1, len(w)): # 填满记忆数组
for j in range(1, max_W+1):
m(i, j)
for i in range(1, len(w)):
for j in range(1, max_W+1):
print(i, '-', j, ':', sum[(i, j)])
print(sum[(len(w)-1, max_W)]) # 注意索引
递归代码Ⅱ:
tr = {(2, 3), (3, 4), (4, 8), (5, 8), (9, 10)}
val = {}
def thief(tr, m):
if tr == set() or m == 0:
val[(tuple(tr), m)] = 0
return 0
elif (tuple(tr), m) in val: # 记忆
return val[(tuple(tr), m)]
else:
vmax = 0
for t in tr: # 取出一个合适的宝物再求处剩下宝物的最大值
if t[0] <= m:
vmax = max(vmax, t[1] + thief(tr-{t}, m-t[0]))
val[(t, m)] = vmax
return vmax
# 秀
print(thief(tr, 20))
迭代
# 从小到大讨论
tr = [None, {'w':2, 'v':3}, {'w':3, 'v':4},
{'w':4, 'v':8}, {'w':5, 'v':8},
{'w':9, 'v':10}]
max_m = 20
val = {(i, w):0 for i in range(len(tr))
for w in range(max_m+1)}
for i in range(1, len(tr)): # 从小到大递推,由于tr的第一项是None,因此得从第一项开始,range[1, len(tr)]
for w in range(1, max_m+1):
if tr[i]['w'] > w: # 注意:这里不是max_m
val[(i, w)] = val[(i-1), w]
else:
val[(i, w)] = max(val[(i-1), w], tr[i]['v'] + val[(i-1), w-tr[i]['w']])
print(val[(len(tr)-1, max_m)])