ShoppingOffers

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, and $3 for B, $4 for C. 
You may pay $4 for 1A and 1B, and $9 for 2A ,2B and 1C. 
You need to buy 1A ,2B and 1C, so you may pay $4 for 1A and 1B (special offer #1), and $3 for 1B, $4 for 1C. 
You cannot add more items, though only $9 for 2A ,2B and 1C.

Note:

  1. There are at most 6 kinds of items, 100 special offers.
  2. For each item, you need to buy at most 6 of them.
  3. You are not allowed to buy more items than you want, even if that would lower the overall price.
 1 import java.util.ArrayList;
 2     import java.util.List;
 3 
 4     /**
 5      * Created by qmq
 6      * Input: [2,5], [[3,0,5],[1,2,10]], [3,2]
 7      * Output: 14
 8      * Explanation:
 9      * There are two kinds of items, A and B. Their prices are $2 and $5 respectively.
10      * In special offer 1, you can pay $5 for 3A and 0B
11      * In special offer 2, you can pay $10 for 1A and 2B.
12      * You need to buy 3A and 2B, so you may pay $10 for 1A and 2B (special offer #2), and $4 for 2A.
13      * note:
14      * There are at most 6 kinds of items, 100 special offers.
15      * For each item, you need to buy at most 6 of them.
16      * You are not allowed to buy more items than you want, even if that would lower the overall price.*
17      *
18      * @ 18-10-8
19      **/
20     class Solution6 {
21 
22         boolean checkvalid(List<Integer> needs, List<Integer> special) {
23             for (int j = 0; j < needs.size(); ++j) {
24                 if (needs.get(j) < special.get(j)) {
25                     return false;
26                 }
27             }
28             return true;
29         }
30 
31         public int shoppingOffers(List<Integer> price, List<List<Integer>> special, List<Integer> needs) {
32 
33             int minPrice = 0;
34             for (int i = 0; i < needs.size(); ++i) {
35                 //不使用折扣方案的价格
36                 minPrice += needs.get(i) * price.get(i);
37             }
38 
39             for (int i = 0; i < special.size(); ++i) {
40                 if (checkvalid(needs, special.get(i))) {
41                     //校验是否符合每个需求量大于优惠方案数量,若均不符合则直接使用不折扣方案
42                     List<Integer> curNeeds = new ArrayList<>();
43                     for (int j = 0; j < needs.size(); ++j) {
44                         curNeeds.add(needs.get(j) - special.get(i).get(j));         // 子需求量 = 当前需求量-方案提供量
45                     }
46                     int tempPrice = shoppingOffers(price, special, curNeeds) + special.get(i).get(needs.size());
47                     //子方案递归选择+当前方案金额
48                     minPrice = Math.min(minPrice, tempPrice);
49                     //获取最低价格,可能不使用折扣方案更便宜
50                 }
51             }
52             return minPrice;
53         }
54     }

需要注意的是可能存在方案数量超出和方案组合并不优惠的情况,所以每次需要加入Math.min(minPrice,tempPrice)的判断和checkValid(needs,special.get(i)),对于选择方案剩余后的继续递归判断,是否能继续使用方案。所以递归的时候需要注意每次执行时的判断条件。

 1 class Solution
 2 {
 3   public:
 4     bool checkvalid(vector<int> &needs, const vector<int> &special)
 5     { //检查当前需求数量若均大于折扣方案数量,则可以使用该折扣方案
 6         for (int j = 0; j < needs.size(); ++j)
 7         {
 8             if (needs[j] < special[j])
 9             {
10                 return false;
11             }
12         }
13         return true;
14     }
15     int shoppingOffers(vector<int> &price, vector<vector<int>> &special, vector<int> &needs)
16     {
17         int minPrice = 0;
18         for (int i = 0; i < needs.size(); ++i)
19         { //不使用折扣方案的价格
20             minPrice += needs[i] * price[i];
21         }
22         for (int i = 0; i < special.size(); ++i)
23         {
24             if (checkvalid(needs, special[i]))
25             {
26                 vector<int> curNeeds;
27                 for (int j = 0; j < needs.size(); ++j)
28                 {
29                     curNeeds.push_back(needs[j] - special[i][j]);
30                 }
31                 int tempPrice = shoppingOffers(price, special, curNeeds) + special[i][needs.size()]; //递归调用剩下的需求数量的最低买价方案
32                 minPrice = min(minPrice, tempPrice);                                                 //获取最低价格,可能不使用折扣方案更便宜
33             }
34         }
35         return minPrice;
36     }
37 };
原文地址:https://www.cnblogs.com/sigmod3/p/9765073.html