博物馆大盗问题 Python

博物馆大盗问题

问题:

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

ItemWeightValue
123
234
348
458
5910

思路:

把 m(i, w) 记为:前 i 个宝物中,组合不超过 w 重量,得到的最大价值。
C:\Users\ldz\AppData\Roaming\Typora\typora-user-images

本题中,从m(1, 1)计算至m(5, 20)
在这里插入图片描述

动态规划代码:

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)
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值