[LeetCode]638. Shopping Offers

- LeetCode

给每种商品的价格、多组不同offer(每个offer内最后一个为价格,前面为每种商品在这个offer内的数量)、最终要买的个数

要求exactly每个商品给定个数,所需要的最少钱

遍历 + 回溯(递归)+ 记忆化搜索(List也可以作为key)

查看每个offer在当前needs下是否valid,如果valid就按照新的needs进行递归

public class Solution {
    Map<List<Integer>, Integer> cache = new HashMap();
    public int shoppingOffers(List<Integer> price, List<List<Integer>> special, List<Integer> needs) {
        if (cache.containsKey(needs)) return cache.get(needs);
        int res = Integer.MAX_VALUE;
        for (int i = 0; i < special.size(); i++) {
        	boolean isValid = true;
        	List<Integer> offer = special.get(i);
        	for (int j = 0; j < needs.size(); j++) {
        		int remain = needs.get(j) - offer.get(j);
        		if (remain < 0) {
        			isValid = false;
        		}
        		needs.set(j, remain);
        	}
        	if (isValid) {
        		res = Math.min(res, shoppingOffers(price, special, needs) + offer.get(needs.size()));
        	}
        	for (int j = 0; j < needs.size(); j++) {
        		needs.set(j, needs.get(j) + offer.get(j));
        	}
        }
        int nonOffer = 0;
        for (int i = 0; i < needs.size(); i++) {
        	nonOffer += needs.get(i) * price.get(i);
        }
        cache.put(needs, Math.min(nonOffer, res));
        return Math.min(nonOffer, res);
    }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值