python数据结构:博物馆大盗问题

博物馆大盗问题

❖大盗潜入博物馆,面前有5件宝物,分别有重量和价值,大盗的背包仅能负重20公斤,请问如何选择宝物,总价值最高?
item weight value
1 2 3
2 3 4
3 4 8
4 5 8
5 9 10
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5RSlg7IQ-1584154561746)(attachment:1.png)]
❖我们把m(i,W)记为:
前i(1<=i<=5)个宝物中,组合不超过W(1<=W<=20)重量,
得到的最大价值m(i, W)应该是m(i-1, W)和m(i-1, W-Wi)+vi两者最大值
我们从m(1, 1)开始计算到m(5, 20)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IIZYoDAc-1584154561748)(attachment:2.png)]

递归+记忆表(备忘录)代码实现

#宝物的重量和价值
tr={(2,3),(3,4),(4,8),(5,8),(9,10)}
#大盗的最大承重
max_w=20

#初始化记忆表m
#字典中的键key是(宝物组合,最大重量),value是最大价值
m={}

def thief(tr,w): 
    #如果宝物tr是空集或者盗贼拿走的宝物重量为0,则直接返回0
    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 #初始值设为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
发布了51 篇原创文章 · 获赞 34 · 访问量 906

猜你喜欢

转载自blog.csdn.net/weixin_43412569/article/details/104856486