# 2646. Minimize the Total Price of the Trips ###### tags: `Leetcode` `Hard` `Dynamic Programming` `DFS` Link: https://leetcode.com/problems/minimize-the-total-price-of-the-trips/description/ ## 思路 首先遍历每一个trip 计算出如果不reduce任何一个price的total price 以及每个点都走了几次 接下来用dp计算最多能reduce多少price 这里计算的时候需要加memo 否则会超时 由于这个graph是一个tree 从任何一个点开始算dp都是一样的结果 ## Code ```java= class Solution { List<List<Integer>> graph; Map<Integer, Integer> freq; int[][] memo; public int minimumTotalPrice(int n, int[][] edges, int[] price, int[][] trips) { graph = new ArrayList<>(); memo = new int[n][2]; for(int i=0; i<n; i++){ graph.add(new ArrayList<>()); memo[i][0] = memo[i][1] = Integer.MAX_VALUE; } for(int[] edge:edges){ graph.get(edge[0]).add(edge[1]); graph.get(edge[1]).add(edge[0]); } freq = new HashMap<>(); int originalPrice = 0; for(int[] trip:trips){ freq.put(trip[0], freq.getOrDefault(trip[0], 0)+1); originalPrice += price[trip[0]]+dfs(trip[0], -1, trip[1], price); } int reduce = Math.max(dp(0, -1, true, price), dp(0, -1, false, price)); return originalPrice-reduce; } public int dfs(int start, int prev, int end, int[] price){ if(start==end) return 0; for(int next:graph.get(start)){ if(next==prev) continue; int nextPrice = dfs(next, start, end, price); if(nextPrice>=0){ freq.put(next, freq.getOrDefault(next, 0)+1); return price[next]+nextPrice; } } return -1; } public int dp(int curr, int prev, boolean canReduce, int[] price){ if(memo[curr][canReduce?0:1]!=Integer.MAX_VALUE) return memo[curr][canReduce?0:1]; int reduce = 0, nextReduce = 0; if(canReduce) reduce += price[curr]/2*freq.getOrDefault(curr, 0); for(int next: graph.get(curr)){ if(next==prev) continue; if(canReduce) nextReduce += dp(next, curr, false, price); else nextReduce += Math.max(dp(next, curr, true, price), dp(next, curr, false, price)); } return memo[curr][canReduce?0:1] = reduce+nextReduce; } } ```