一个小偷在某个商店发现有n个商品,第i个商品价值 V i V_i Vi元,中 W i W_i Wi千克。他希望拿走的价值尽量高,但他的背包最多只能容纳W千克的东西。他应该拿走拿些商品?
- 0-1背包: 对于一个商品,小偷要么把它完整拿走,要么留下。不能只拿走一部分,或把一个商品拿走多次(商品为金条)
- 分数背包: 对于一个商品,小偷可以拿走其中任意一部分(商品为金砂)
例如
商品1:
V
1
V_1
V1=60
W
1
W_1
W1=10
商品2:
V
2
V_2
V2=100
W
2
W_2
W2=20
商品3:
V
3
V_3
V3=60
W
3
W_3
W3=30
背包容量: W=50
对于0-1背包和分数背包,贪心算法是否都能得到最优解?为什么?
#! /usr/bin/env python
# -*- coding: utf-8 -*-
goods = [(60, 10),(100, 20),(120, 30)] # 每个商品元组表示(价格, 重量)
#降序排列
goods.sort(key=lambda x: x[0]/x[1], reverse=True)
#贪心要拿值钱的 w填满
def fractional_backpack(goods, w):
print(goods)
print(w)
m = [0 for _ in range(len(goods))]
print(m)
total_v = 0
#i是索引
for i, (prize, weight) in enumerate(goods):
print(w,weight)
if w >= weight:
m[i] = 1
total_v += prize
#w是背包的重量开始减少 weight是商品的重量
w -= weight
else:
m[i] = w / weight
total_v += m[i] * prize
#一个商品都拿不走了
w = 0
break
return total_v, m
#背包就是50
print(fractional_backpack(goods, 50))