Given
n
balloons, indexed from0
ton-1
. Each balloon is painted with a number on it represented by arraynums
. You are asked to burst all the balloons. If the you burst ballooni
you will getnums[left] * nums[i] * nums[right]
coins. Hereleft
andright
are adjacent indices ofi
. After the burst, theleft
andright
then becomes adjacent.Find the maximum coins you can collect by bursting the balloons wisely.
Note:
(1) You may imaginenums[-1] = nums[n] = 1
. They are not real therefore you can not burst them.
(2) 0 ≤n
≤ 500, 0 ≤nums[i]
≤ 100Example:
Given
[3, 1, 5, 8]
Return
167
1
2
3 > 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
>
题意:戳破一个气球(序号为i)就可以得到nums[i-1]nums[i]\nums[i+1]的得分,求问怎么得戳破所有气球然后得分最高。
一开始看这个题真的是一点思路都没有,别说敲代码实现了,就是自己手动算的都不知道从何而算起。
没有思路的主要问题是没办法把这个题目划分为子问题,好像觉得在每一步要戳破哪个很难决定。最后看了discuss后恍然大悟,要这么划分自问题的:
要戳破[i,j]区间的气球,那么如果k为最后一个戳破的,那么以d[i][j]表示得分,则
1 | dp[i][j] = { |
这样子问题不就划分好了吗~?
需要计算最大值,那么只要按个遍历[i,j]中的每一个可能值k,然后维护最大值即可。表示如下:
1 | for k in [i,j]: |
虽然到此思路有了,但是一开始提交还是错掉了。主要是对dp二维表的计算顺序搞错了!
错误的计算顺序:
1 | // |
错误主要是因为:跟之前的第i行的结果依赖第i-1行的思想不一样,这次的是i+1行对i行也有影响,所以对角线的要先算,比如在计算dp[1][2]时,当k=1时
1 | dp[1][2] = max(dp[1][2],dp[1][0]+dp[2][2]+balloons[0]*ballons[1]*ballons[3])//这时要dp[1][2]就得先有dp[2][2] |
正确的AC代码:
1 | // |