---
# System prepended metadata

title: 0638. Shopping Offers
tags: [Leetcode, DFS+Memorization, Medium]

---

# 0638. Shopping Offers
###### tags: `Leetcode` `Medium` `DFS+Memorization`
Link: https://leetcode.com/problems/shopping-offers/
## 思路
memorization里面需要记录每一组needs的cost的最小值
如果直接用list of integer当map的key比较麻烦 
所以把整个list用```needs.toString()```转成string
但如果直接这样写
[4,9,6]
[[0,1,1,5],[2,3,2,1],[1,2,1,7],[1,0,0,2]]
[4,5,3]
Output : 19 Expected: 10
这个testcase会有问题
因为expected应该用后三个 但是[2,2,1]这个need (本来最佳解应该是由```needs-special[1]```得到) 但它会先从```needs-special[0]-special[2]-2*special[3]```得到
所以为了区分在key里面还加了start
## Code
```java=
class Solution {
    public int shoppingOffers(List<Integer> price, List<List<Integer>> special, List<Integer> needs) {
        Map<String, Integer> minCost = new HashMap<>();
        return dfs(price, special, needs, minCost, 0);
    }
    private int dfs(List<Integer> price, List<List<Integer>> special, List<Integer> needs, Map<String, Integer> minCost, int start){
        if(minCost.containsKey(needs.toString()+start)) return minCost.get(needs.toString()+start);
        int min = directPurchase(price, needs);
        for(int i=start; i<special.size(); i++){
            List<Integer> nextNeeds = new ArrayList<>();
            for(int j=0; j<needs.size(); j++){
                if(needs.get(j) < special.get(i).get(j)) break;
                nextNeeds.add(needs.get(j)-special.get(i).get(j));
            }
            if(nextNeeds.size()==needs.size()){
                min = Math.min(min, dfs(price, special, nextNeeds, minCost, i)+special.get(i).get(special.get(i).size()-1));
            }
        }
        minCost.put(needs.toString()+start, min);
        return min;
    }
    private int directPurchase(List<Integer> price, List<Integer> needs){
        int cost = 0;
        for(int i=0; i<needs.size(); i++){
            cost += price.get(i)*needs.get(i);
        }
        return cost;
    }
}
```