Leetcode 638. 大礼包
 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 };

 

posted on 2024-11-03 13:47  greenofyu  阅读(7)  评论(0编辑  收藏  举报