Java - Recursive -> Memoization -> 2D Bottom Up
\n- If we currently have a range of numbers from indices \'i -> k\'\n\t- Then the two numbers at \'i\' and \'k\' can be the corners of two vertices\n\t\t- Then 
```\n- If we currently have a range of numbers from indices \'i -> k\'\n\t- Then the two numbers at \'i\' and \'k\' can be the corners of two vertices\n\t\t- Then the last corner \'j\' can be a number from indices \'i + 1 -> k - 1\'\n\t- We can then continue to build triangles using the indices from \'i -> j\' and \'j -> k\'\n- We will pick the index \'j\' that will give us the least total score\n```\n```\npublic class MinimumScoreTriangulationOfPolygonRecursiveApproach {\n    public int minScoreTriangulation(int[] A) {\n        return minScoreTriangulation(0, A.length - 1, A);\n    }\n\n    private int minScoreTriangulation(int i, int k, int[] A) {\n        if (k - i <= 1) return 0;\n\n        int minScore = Integer.MAX_VALUE;\n\n        for (int j = i + 1; j < k; j++) {\n            minScore = Math.min(minScore,\n                    minScoreTriangulation(i, j, A) + minScoreTriangulation(j, k, A) + (A[i] * A[j] * A[k]));\n        }\n\n        return minScore;\n    }\n}\n```\n```\npublic class MinimumScoreTriangulationOfPolygonMemoizationApproach {\n    public int minScoreTriangulation(int[] A) {\n        return minScoreTriangulation(0, A.length - 1, A, new int[A.length][A.length]);\n    }\n\n    private int minScoreTriangulation(int i, int k, int[] A, int[][] memo) {\n        if (k - i <= 1) return 0;\n        if (memo[i][k] != 0) return memo[i][k];\n\n        int minScore = Integer.MAX_VALUE;\n\n        for (int j = i + 1; j < k; j++) {\n            minScore = Math.min(minScore,\n                    minScoreTriangulation(i, j, A, memo) + minScoreTriangulation(j, k, A, memo) + (A[i] * A[j] * A[k]));\n        }\n\n        return memo[i][k] = minScore;\n    }\n}\n```\n```\npublic class MinimumScoreTriangulationOfPolygonBottomUp2DApproach {\n    public int minScoreTriangulation(int[] A) {\n        int[][] minScores = new int[A.length][A.length];\n\n        for (int i = A.length - 1; i >= 0; i--) {\n            for (int k = 0; k < A.length; k++) {\n                if (k - i <= 1) continue;\n\n                minScores[i][k] = Integer.MAX_VALUE;\n\n                for (int j = i + 1; j < k; j++) {\n                    minScores[i][k] = Math.min(minScores[i][k],\n                            minScores[i][j] + minScores[j][k] + A[i] * A[j] * A[k]);\n                }\n            }\n        }\n\n        return minScores[0][A.length - 1];\n    }\n}\n```
[]