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:
- There are at most 6 kinds of items, 100 special offers.
- For each item, you need to buy at most 6 of them.
- 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 };