JAVA DP:
public final int shoppingOffers(List<Integer> price, List<List<Integer>> special, List<Integer> needs) { Map<String, Integer> cache = new HashMap<String, Integer>(); return search(price, special, needs, cache); } private final int search(List<Integer> prices, List<List<Integer>> specials, List<Integer> needs, Map<String, Integer> cache) { int res = 0; String key = ""; for (int i = 0; i < needs.size(); i++) key += "," + needs.get(i); if (cache.containsKey(key)) return cache.get(key); for (int i = 0; i < needs.size(); i++) res += prices.get(i) * needs.get(i); if (res == 0) return 0; for (int i = 0; i < specials.size(); i++) { List<Integer> special = specials.get(i), clone = new ArrayList<Integer>(needs); boolean canBuy = true; for (int j = 0; j < needs.size(); j++) { int diff = clone.get(j) - special.get(j); if (diff < 0) { canBuy = false; break; } clone.set(j, diff); } if (canBuy) res = Math.min(res, search(prices, specials, clone, cache) + special.get(special.size()-1)); } cache.put(key, res); return res; }
JS DP:
/** * @param {number[]} price * @param {number[][]} special * @param {number[]} needs * @return {number} */ var shoppingOffers = function (price, specials, needs) { return dfs(price, specials, needs, new Map()); } var dfs = function (price, specials, needs, cache) { let re = 0, key = 0; for (let i = 0; i < needs.length; i++) { re += needs[i] * price[i]; key += "," + needs[i]; } if (re == 0) return 0; if (cache.has(key)) return cache.get(key); for (let i = 0; i < specials.length; i++) { let special = specials[i], clone = needs.slice(), canBuy = true; for (let j = 0; j < clone.length; j++) { let diff = clone[j] - special[j]; if (diff < 0) { canBuy = false; break; } clone[j] = diff; } if (canBuy) re = Math.min(re, dfs(price, specials, clone, cache) + special[special.length - 1]); } cache.set(key, re); return re; };