Leetcode――638. Shopping Offers

匿名 (未验证) 提交于 2019-12-03 00:29:01

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 2and5 respectively.
In special offer 1, you can pay 5for3Aand0BInspecialoffer2,youcanpay10 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 2,and3 for B, 4forC.Youmaypay4 for 1A and 1B, and 9for2A,2Band1C.Youneedtobuy1A,2Band1C,soyoumaypay4 for 1A and 1B (special offer #1), and 3for1B,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;     } }
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!