题目:
Given n
balloons, indexed from 0
to n-1
.
Each balloon is painted with a number on it represented by array nums
. You are asked
to burst all the balloons. If the you burst balloon i
you will get nums[left]
* nums[i] * nums[right]
coins. Here left
and right
are
adjacent indices of i
. After the burst, the left
and right
then
becomes adjacent.
Find the maximum coins you can collect by bursting the balloons wisely.
Note:(1) You may imagine
nums[-1]
= nums[n] = 1
. They are not real therefore you can not burst them.(2) 0 ≤
n
≤
500, 0 ≤ nums[i]
≤
100
Example:
Given [3, 1, 5, 8]
Return 167
nums = [3,1,5,8] --> [3,5,8] --> [3,8] --> [8] --> [] coins = 3*1*5 + 3*5*8 + 1*3*8 + 1*8*1 = 167
思路:
leetcode把这道题归类为分治,但是我觉得这道题用动态规划去理解更为合适。声明一个二维数组,定义dp[l][h]表示为以序号为l和h为边界的气球串(h>l),打破l + 1到h - 1之间的所有球所能取得的最大金币数量。考虑在nums[l...h]中,序号为m(l<m<h)的是其中一个气球,把它看作是整个序列中最后一个打破的(不是第一个,这点很关键),就能推导出它的转移方程dp[l][h] = max(dp[l][h], dp[l][m] + dp[m][h] + nums[l]*nums[m]*nums[h])。首先要对nums做些处理,要在它的头尾个插入1,由此dp[0][n+1]则是最终返回的结果。因为最近在学习python,所以这题尝试用python来写程序。
程序:
def maxCoins(nums):
nums.append(1)
nums.insert(0,1)
dp = [[0 for i in range(len(nums))] for i in range(len(nums))]
n = len(nums)
for k in range(2,n):
for l in range(0,n - k):
h = l + k
for m in range(l + 1,h):
dp[l][h] = max(dp[l][h],nums[l] * nums[m] * nums[h] + dp[l][m] + dp[m][h])
return dp[0][len(nums) - 1]