638. 大礼包
from functools import lru_cache
class Solution:
def shoppingOffers(self, price: List[int], special: List[List[int]], needs: List[int]) -> int:
# 递归所有可能的优惠组合
@lru_cache(None)
def dfs(needs):
res = sum(need*p for need, p in zip(needs, price))
for s in special:
# 更新 needs,减去礼包能够提供的数量
# 过滤掉负数(礼包超过需要购买数量),长度会减小。
new = [need - s for need, s in zip(needs, sp) if need >= s]
if len(new) == n:
res = min(res, dfs(tuple(new)) + sp[-1])
# res = min(res, dfs(new) + s[-1])
return res
n = len(needs)
# 过滤无效的礼包
special = [sp for sp in special if sum(price[i]*sp[i] for i in range(n)) > sp[-1]]
# 使用tuple,用lru加速
return dfs(tuple(needs))
# return dfs(needs)
# class Solution:
# def shoppingOffers(self, price: List[int], special: List[List[int]], needs: List[int]) -> int:
# res = sum(p * n for p, n in zip(price, needs))
# return min([res] + [sp[-1] + self.shoppingOffers(price, special, [n - c for n, c in zip(needs, sp[:-1])]) for sp in special if not any(n < o for n, o in zip(needs, sp))])
class Solution:
def shoppingOffers(self, price: List[int], special: List[List[int]], needs: List[int]) -> int:
@cache
def dfs(needs: tuple) -> int:
return min([sum(p * n for p, n in zip(price, needs))] + [sp[-1] + dfs(tuple(n - c for n, c in zip(needs, sp[:-1]))) for sp in special if not any(n < o for n, o in zip(needs, sp))])
return dfs(tuple(needs))