1 class Solution { 2 public: 3 map<vector<int>, int> memo; 4 5 int shoppingOffers(vector<int>& price, vector<vector<int>>& special, vector<int>& needs) { 6 int n = price.size(); 7 8 // 过滤不需要计算的大礼包,只保留需要计算的大礼包 9 vector<vector<int>> filterSpecial; 10 for (auto & sp : special) { 11 int totalCount = 0, totalPrice = 0; 12 for (int i = 0; i < n; ++i) { 13 totalCount += sp[i]; 14 totalPrice += sp[i] * price[i]; 15 } 16 if (totalCount > 0 && totalPrice > sp[n]) { 17 filterSpecial.emplace_back(sp); 18 } 19 } 20 21 return dfs(price, special, needs, filterSpecial, n); 22 } 23 24 // 记忆化搜索计算满足购物清单所需花费的最低价格 25 int dfs(vector<int> price,const vector<vector<int>> & special, vector<int> curNeeds, vector<vector<int>> & filterSpecial, int n) { 26 if (!memo.count(curNeeds)) { 27 int minPrice = 0; 28 for (int i = 0; i < n; ++i) { 29 minPrice += curNeeds[i] * price[i]; // 不购买任何大礼包,原价购买购物清单中的所有物品 30 } 31 for (auto & curSpecial : filterSpecial) { 32 int specialPrice = curSpecial[n]; 33 vector<int> nxtNeeds; 34 for (int i = 0; i < n; ++i) { 35 if (curSpecial[i] > curNeeds[i]) { // 不能购买超出购物清单指定数量的物品 36 break; 37 } 38 nxtNeeds.emplace_back(curNeeds[i] - curSpecial[i]); 39 } 40 if (nxtNeeds.size() == n) { // 大礼包可以购买 41 minPrice = min(minPrice, dfs(price, special, nxtNeeds, filterSpecial, n) + specialPrice); 42 } 43 } 44 memo[curNeeds] = minPrice; 45 } 46 return memo[curNeeds]; 47 } 48 };