|
| 1 | +# Dynamic Programming Memoization | 30 Lines | O(n³) | 6ms |
| 2 | + |
| 3 | +# Intuition |
| 4 | +This is a classic interval dynamic programming problem. To triangulate a polygon optimally, we need to find the best way to divide it into triangles. Each triangulation choice affects the total score, so we need to try all possible divisions and pick the minimum. |
| 5 | + |
| 6 | +# Approach |
| 7 | +Use memoized recursion where `findMinTriangulationScore(i, j)` returns the minimum score to triangulate the polygon segment from vertex i to vertex j. For each segment, try all possible middle vertices k to form triangle (i, k, j), then recursively solve the left and right subproblems. The base case is when vertices are adjacent (no triangulation needed). |
| 8 | + |
| 9 | +# Complexity |
| 10 | +- Time complexity: $$O(n^3)$$ |
| 11 | +- Space complexity: $$O(n^2)$$ for memoization table |
| 12 | + |
| 13 | +# Code |
| 14 | +```typescript |
| 15 | +const minScoreTriangulation = (values: number[]): number => { |
| 16 | + const polygonSize = values.length; |
| 17 | + const memo: number[][] = Array.from( |
| 18 | + { length: polygonSize }, |
| 19 | + () => Array.from({ length: polygonSize }, () => 0) |
| 20 | + ); |
| 21 | + |
| 22 | + const findMinTriangulationScore = (leftVertex: number, rightVertex: number): number => { |
| 23 | + if (leftVertex + 1 === rightVertex) { |
| 24 | + return 0; |
| 25 | + } |
| 26 | + |
| 27 | + if (memo[leftVertex][rightVertex] > 0) { |
| 28 | + return memo[leftVertex][rightVertex]; |
| 29 | + } |
| 30 | + |
| 31 | + let minScore = Number.MAX_SAFE_INTEGER; |
| 32 | + |
| 33 | + for (let middleVertex = leftVertex + 1; middleVertex < rightVertex; middleVertex++) { |
| 34 | + const leftSubproblem = findMinTriangulationScore(leftVertex, middleVertex); |
| 35 | + const rightSubproblem = findMinTriangulationScore(middleVertex, rightVertex); |
| 36 | + const currentTriangleScore = values[leftVertex] * values[middleVertex] * values[rightVertex]; |
| 37 | + |
| 38 | + const totalScore = leftSubproblem + rightSubproblem + currentTriangleScore; |
| 39 | + minScore = Math.min(minScore, totalScore); |
| 40 | + } |
| 41 | + |
| 42 | + memo[leftVertex][rightVertex] = minScore; |
| 43 | + return minScore; |
| 44 | + }; |
| 45 | + |
| 46 | + return findMinTriangulationScore(0, polygonSize - 1); |
| 47 | +}; |
| 48 | +``` |
0 commit comments