题目
类型:Bit Manipulation
解题思路
代码
package bitManipulation;
import java.util.*;
public class ShoppingOffers {
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);
}
// 记忆化搜索计算满足购物清单所需花费的最低价格
public int dfs(List<Integer> price, List<List<Integer>> special, List<Integer> curNeeds, List<List<Integer>> filterSpecial, int n) {
if (!memo.containsKey(curNeeds)) {
int minPrice = 0;
for (int i = 0; i < n; ++i) {
minPrice += curNeeds.get(i) * price.get(i); // 不购买任何大礼包,原价购买购物清单中的所有物品
}
for (List<Integer> curSpecial : filterSpecial) {
int specialPrice = curSpecial.get(n);
List<Integer> nxtNeeds = new ArrayList<Integer>();
for (int i = 0; i < n; ++i) {
if (curSpecial.get(i) > curNeeds.get(i)) { // 不能购买超出购物清单指定数量的物品
break;
}
nxtNeeds.add(curNeeds.get(i) - curSpecial.get(i));
}
if (nxtNeeds.size() == n) { // 大礼包可以购买
minPrice = Math.min(minPrice, dfs(price, special, nxtNeeds, filterSpecial, n) + specialPrice);
}
}
memo.put(curNeeds, minPrice);
}
return memo.get(curNeeds);
}
public static void main(String[] args) {
ShoppingOffers shoppingOffers = new ShoppingOffers();
List<Integer> price = Arrays.asList(2,5);
List<Integer> needs = Arrays.asList(3,2);
List<List<Integer>> special = Arrays.asList(Arrays.asList(3, 0, 5), Arrays.asList(1, 2, 10));
System.out.println(shoppingOffers.shoppingOffers(price, special, needs));
}
}