博物馆大盗问题 Python

博物馆大盗问题

问题:

大盗潜入博物馆,面前有5件宝物,分别有重量w和价值v,大盗的背包仅能负重20 kg,请问如何选择宝物,总价值最高?

Item Weight Value
1 2 3
2 3 4
3 4 8
4 5 8
5 9 10

思路:

把 m(i, w) 记为:前 i 个宝物中,组合不超过 w 重量,得到的最大价值。
博物馆大盗问题 Python_第1张图片

本题中,从m(1, 1)计算至m(5, 20)
博物馆大盗问题 Python_第2张图片

动态规划代码:

tr = [
    None,
    {
     'w': 2, 'v': 3},
    {
     'w': 3, 'v': 4},
    {
     'w': 4, 'v': 8},
    {
     'w': 5, 'v': 8},
    {
     'w': 9, 'v': 10}
]
max_weight = 20

# 初始化二维表格 m[(i, w)]
m = {
     (i, w):0 for i in range(len(tr)) for w in range(max_weight + 1)}

# 逐个填写二位表格
for i in range(1, len(tr)):
    for w in range(1, max_weight + 1):
        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'])

print m[(len(tr)-1, max_weight)]

递归代码:

tr = {
     (2, 3), (3, 4), (4, 8), (5, 8), (9, 10)}  # 集合
max_weight = 20

m = {
     }  # 记忆表格m

def thief(tr, w):
    # 终止条件
    if tr == set() or w == 0:
        m[(tuple(tr), w)] = 0
        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_weight)

你可能感兴趣的:(python,动态规划,leetcode,算法,数据结构)