|
| 1 | +class Solution { |
| 2 | +public: |
| 3 | + // Recursive function to calculate the minimum cost of combining leaf values |
| 4 | + // `arr`: The input array of leaf values |
| 5 | + // `maxi`: Precomputed map containing the maximum values for all subarrays |
| 6 | + // `left`, `right`: The current range being considered |
| 7 | + // `dp`: Memoization table to store results of subproblems |
| 8 | + int solve(vector<int>& arr, map<pair<int, int>, int>& maxi, int left, int right, vector<vector<int>>& dp) { |
| 9 | + // Base case: If there is only one element, the cost is zero |
| 10 | + if(left == right) return 0; |
| 11 | + |
| 12 | + // If the result for this subproblem is already computed, return it |
| 13 | + if(dp[left][right] != -1) return dp[left][right]; |
| 14 | + |
| 15 | + int mini = INT_MAX; // Initialize minimum cost to a very high value |
| 16 | + |
| 17 | + // Try every possible split point `i` between `left` and `right` |
| 18 | + for(int i = left; i < right; i++) { |
| 19 | + // Calculate the cost of this split: |
| 20 | + // 1. `maxi[{left, i}] * maxi[{i+1, right}]`: Cost of combining the maximum leaf values from the two partitions |
| 21 | + // 2. Recursive calls to solve for the left and right partitions |
| 22 | + mini = min(mini, |
| 23 | + maxi[{left, i}] * maxi[{i+1, right}] + |
| 24 | + solve(arr, maxi, left, i, dp) + |
| 25 | + solve(arr, maxi, i+1, right, dp) |
| 26 | + ); |
| 27 | + } |
| 28 | + |
| 29 | + // Store the result in the `dp` table for future use |
| 30 | + return dp[left][right] = mini; |
| 31 | + } |
| 32 | + |
| 33 | + int mctFromLeafValues(vector<int>& arr) { |
| 34 | + int n = arr.size(); |
| 35 | + |
| 36 | + // `dp` table to memoize results for subproblems |
| 37 | + // `dp[i][j]` will store the minimum cost to combine leaf nodes in the range `[i, j]` |
| 38 | + vector<vector<int>> dp(n + 1, vector<int>(n + 1, -1)); |
| 39 | + |
| 40 | + // Precompute the maximum values for all subarrays `[i, j]` |
| 41 | + map<pair<int, int>, int> maxi; |
| 42 | + for(int i = 0; i < arr.size(); i++) { |
| 43 | + // For subarray of size 1, the maximum is the element itself |
| 44 | + maxi[{i, i}] = arr[i]; |
| 45 | + for(int j = i + 1; j < arr.size(); j++) { |
| 46 | + // For larger subarrays, the maximum is the larger of: |
| 47 | + // - The current element `arr[j]` |
| 48 | + // - The maximum of the previous subarray `[i, j-1]` |
| 49 | + maxi[{i, j}] = max(arr[j], maxi[{i, j-1}]); |
| 50 | + } |
| 51 | + } |
| 52 | + |
| 53 | + // Solve the problem for the full range `[0, n-1]` using the recursive function |
| 54 | + return solve(arr, maxi, 0, arr.size() - 1, dp); |
| 55 | + } |
| 56 | +}; |
0 commit comments