Python DP N^3 Solutions
Analysis:\nWe need to find a way to divide the problems. If we start from the first balloon, we can't determine the left/right for the number in each sub-proble
Analysis:\nWe need to find a way to divide the problems. If we start from the first balloon, we can't determine the left/right for the number in each sub-problem, If we start from the last balloon, we can. \nWe can see the transformation equation is very similar to the one for matrix multiplication.\n\n    dp[i][j] = max(dp[i][j], nums[i] * nums[k] * nums[j] + dp[i][k] + dp[k][j]) # i < k < j\n\nThis is a typical interval DP problem. Because the order of the number extracted matters, we need to do a O(n^3) DP. If we only need to expand the interval to the left or right, we only need to do a O(n^2) DP. \n\nTop-down:\n\n    class Solution(object):\n        def maxCoins(self, nums):\n            """\n            :type nums: List[int]\n            :rtype: int\n            """\n            nums = [1] + nums + [1]\n            n = len(nums)\n            dp = [[0] * n for _ in xrange(n)]\n    \n            def calculate(i, j):\n                if dp[i][j] or j == i + 1: # in memory or gap < 2\n                    return dp[i][j]\n                coins = 0\n                for k in xrange(i+1, j): # find the last balloon\n                    coins = max(coins, nums[i] * nums[k] * nums[j] + calculate(i, k) + calculate(k, j))\n                dp[i][j] = coins\n                return coins\n    \n            return calculate(0, n-1)\n\nBottom-up:\n   \n\n     class Solution(object):\n            def maxCoins(self, nums):\n                """\n                :type nums: List[int]\n                :rtype: int\n                """\n                nums = [1] + nums + [1] # build the complete array \n                n = len(nums)\n                dp = [[0] * n for _ in xrange(n)]\n        \n                for gap in xrange(2, n):\n                    for i in xrange(n-gap):\n                        j = i + gap\n                        for k in xrange(i+1, j):\n                            dp[i][j] = max(dp[i][j], nums[i] * nums[k] * nums[j] + dp[i][k] + dp[k][j])\n                return dp[0][n-1]
['Python']