https://leetcode.com/problems/shopping-offers/description/
Example 1:
Input: [2,5], [[3,0,5],[1,2,10]], [3,2]
Output: 14
Explanation:
There are two kinds of items, A and B. Their prices are 5 respectively.
In special offer 1, you can pay 10 for 1A and 2B.
You need to buy 3A and 2B, so you may pay 4 for 2A.
Example 2:
Input: [2,3,4], [[1,1,0,4],[2,2,1,9]], [1,2,1]
Output: 11
Explanation:
The price of A is 3 for B, 4 for 1A and 1B, and 4 for 1A and 1B (special offer #1), and 4 for 1C.
You cannot add more items, though only $9 for 2A ,2B and 1C.
题目要求购物的总金额最小,这里给定三个参数public int shoppingOffers(List<Integer> price, List<List<Integer>> special, List<Integer> needs)
,第一个参数代表价格集合,第二个参数代表存在的套餐,第三个参数代表需要的商品的数量。
按照Example 1:进行分析就是:题目中给定的价格集合为[2,5]表示,商品A的价格为2,商品B的价格为5;第二个参数,给定的是[[3,0,5], [1,2,10]]表示给定两个优惠套餐,套餐一:买3个A,0个B一共花费5元,套餐二:1个A,2个B花费10;第三个参数,[3,2]表示商品A买3个,商品B卖2个。
现在要求买到的商品一定要与需要购买的商品个数完全一样,不能大于需要购买的商品数,求所有购买方案中花钱做少的那个花了多少钱。
使用回溯+DFS,这里需要比较直接买和使用套餐的情况,而且可以一部分使用套餐一部分使用递归
class Solution { public int shoppingOffers(List<Integer> price, List<List<Integer>> special, List<Integer> needs) { return shopping(price, special, needs, 0); } private int shopping(List<Integer> price, List<List<Integer>> special, List<Integer> needs, int index) { //用来记录如果直接买这些商品需要花费的价格 int local_min = direction(price, needs); for(int i = index; i < special.size(); i++) { //当前商品还有多少需要买 List<Integer> needsLeft = new ArrayList<>(); //当前是第i个特价的special List List<Integer> offer = special.get(i); //遍历needs需要多少商品个数的集合,知道遍历到最后一个商品个数为止 for(int j = 0; j < needs.size(); j ++) { //如果需要的商品个数小于特价套餐中提供的个数,则不符合条件直接返回 //因为题意要求必须买正好个数的商品,不可以多买 //如果不符合题意,则将剩余的商品变量置为null if(needs.get(j) < offer.get(j)) { needsLeft = null; break; } //将每个商品剩余的数量添加到needsLeft集合中 needsLeft.add(needs.get(j) - offer.get(j)); } //如果needsLeft集合不为Null,则说明前面的特价商品满足题意,则递归向下判断 if(needsLeft != null) { local_min = Math.min(local_min, offer.get(offer.size() - 1) + shopping(price, special, needsLeft, i)); } } return local_min; } private int direction(List<Integer> price, List<Integer> needs) { int total = 0; for(int i = 0; i < needs.size(); i++) { total += price.get(i) * needs.get(i); } return total; } }