题目
类型: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));}}
