背包变化



所以我有一系列优惠券,每张优惠券都有价格和可以从中购买的商品数量。我只能从优惠券中购买给定的商品数量,不多也不少。如何找到获得所需数量的优惠券商品的最低成本(如果不可能,则返回-1)?

例如,在有 4 张优惠券:"10 美元买 3"、"4 美元买 2"、"4 美元买2"和"3 美元买 1",以及 4 件要购买的商品,最低成本为 8 美元。

背包致力于寻找最大值,但至少它会继续不考虑任何优惠券并给出 0 的答案。

这是我的代码:

int minimumCost(coupon_t coupons[], int numCoupons, int units) {
if (units <= 0 || numCoupons <= 0)
return 0;
if (coupons[numCoupons-1].quantity > units)
return minimumCost(coupons, numCoupons-1, units);
coupon_t coupon = coupons[numCoupons-1];
return min(coupon.price + minimumCost(coupons, numCoupons-1, units-coupon.quantity),
minimumCost(coupons, numCoupons-1, units));
}

对此多想了一点。正如你所说,关键是处理0.在典型的背包代码中,0有两个含义:"不买"和"不能买"。拆分这些似乎有效:

def minimum_cost(coupons, units, coupon_no=0):
if units < 0 or coupon_no == len(coupons):
# special value for "impossible"
return None
if units == 0:
# no more space, so we're not buying anything else
return 0
quantity, price = coupons[coupon_no]
next_coupon = coupon_no + 1
if quantity > units:
return minimum_cost(coupons, units, next_coupon)
pre_purchase_value_when_used = minimum_cost(coupons, units - quantity, next_coupon)
value_when_unused = minimum_cost(coupons, units, next_coupon)
# return whichever is not impossible, or cheaper of two possibilities:
if pre_purchase_value_when_used is None:
return value_when_unused
elif value_when_unused is None:
return pre_purchase_value_when_used + price
else:
return min(pre_purchase_value_when_used + price, value_when_unused)
coupons = [[3, 10], [2, 4], [2, 4], [1, 3]]
units = 4
cost = minimum_cost(coupons, units)
print(cost)
# => 8

(请注意,递归不是动态编程,除非您缓存函数结果,尽管使用它使用表应该不会太难。关于动态规划的关键见解是使用存储来避免重新计算我们已经计算过的东西。

最新更新