class Solution {
Map<List<Integer>, Integer> memo = new HashMap<>();
public int shoppingOffers(List<Integer> price, List<List<Integer>> special, List<Integer> needs) {
int n = price.size();
// 过滤掉不需要计算的大礼包,只保留需要计算的大礼包
List<List<Integer>> filterSpecial = new ArrayList<>();
for (List<Integer> sp : special){
int totalCount = 0, totalPrice = 0;
// 计算大礼包的价格
for (int i = 0; i < n; i++){
totalCount += sp.get(i);
// 计算这个物品的价格
totalPrice += sp.get(i) * price.get(i);
}
if (totalCount > 0 && totalPrice > sp.get(n)){
filterSpecial.add(sp);
}
}
return dfs(price, special, needs, filterSpecial, n);
}
private int dfs(List<Integer> price, List<List<Integer>> special, List<Integer> needs, List<List<Integer>> filterSpecial, int n ){
if (!memo.containsKey(needs)){
int minPrice = 0;
for (int i = 0; i < n; i++){
minPrice += needs.get(i) * price.get(i);
}
for (List<Integer> curSpecial : filterSpecial){
int specialPrice = curSpecial.get(n);
List<Integer> nextNeeds = new ArrayList<>();
for (int i = 0; i < n; i++){
if (curSpecial.get(i) > needs.get(i) ){
break;
}
nextNeeds.add(needs.get(i) - curSpecial.get(i));
}
if (nextNeeds.size() == n){
minPrice = Math.min(minPrice, dfs(price, special, nextNeeds, filterSpecial, n) + specialPrice);
}
}
memo.put(needs, minPrice);
}
return memo.get(needs);
}
}