Problem
You are given n
balloons, indexed from 0
to n - 1
. Each balloon is painted with a number on it represented by an array nums
. You are asked to burst all the balloons.
If you burst the ith
balloon, you will get nums[i - 1] * nums[i] * nums[i + 1]
coins. If i - 1
or i + 1
goes out of bounds of the array, then treat it as if there is a balloon with a 1
painted on it.
Return the maximum coins you can collect by bursting the balloons wisely.
Example 1:
1 | Input: nums = [3,1,5,8] |
Example 2:
1 | Input: nums = [1,5] |
Constraints:
n == nums.length
1 <= n <= 500
0 <= nums[i] <= 100
Analysis
这道题目给出一个数组nums
,每次去除掉一个数字nums[i]
,去除数字的cost是nums[i - 1] * nums[i] * nums[i + 1]
。这道题目其实和之前多边形算三角形partition很类似,都是用dp,但是dp的定义有点不同。之前的题目我们可以限定i
和j
两个顶点,让k
在[i + 1, j - 1]
之间走,每次的cost就是nums[i] * nums[k] * nums[j]
。
假设我们用同样的思路去设计,每次的cost是nums[k - 1] * nums[k] * nums[k + 1]
吗?这看上去是正确,但是有问题。问题在于递归左右两边的时候helper(i, k - 1)
和helper(k + 1, j)
。我们只看左边helper(i, k - 1)
,当左边部分把nums[k - 1]
这个位置去除后,在计算去除nums[k]
的时候就不能用nums[k - 1] * nums[k] * nums[k + 1]
了,因为现在nums[k - 1]
并不是nums[k]
左边的数了,因为它已经被去除掉了。所以这里的定义要反过来,定义的是k
这个数字最后被去除掉,所以我们递归处理左右两边,处理完之后,左边[i, k - 1]
都被去除掉了,右边[k + 1, j]
也被去除掉了,所以我就可以计算当前的cost为nums[i - 1] * nums[k] * nums[j + 1]
。
Solution
因为这道题目涉及到了两个边界的计算,为了使得代码逻辑统一处理,我们先在处理前在数组的前后各加一个1,所以处理的区间就是[1, n - 2]
了。
Code
1 | class Solution { |
Summary
这道题目是非常经典的区间类型dp,其套路一般是确定一个范围,然后把范围中的每个值都遍历一遍,对每个位置的计算结果维护极大值或极小值,最后用来更新这个区间的结果(通常是一个记忆化数组,dp数组)。这道题目的分享到这里,感谢你的支持!