312. Burst Balloons
有趣的一个决策选择题
题干:
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.
解释:
给一排的气球,每次扎了之后会得到左乘右乘中间的硬币,要求寻找最大的获取硬币的方式。
思考:
这个题最初的想法肯定是dfs+memo来做,这个想法其实并不是很难,但是这个题长度为500,用dfs做时间复杂度肯定是要炸的。那么结论就很清晰了,百分百是dp。但是dp有问题,戳破一个气球之后,相邻的两部分之间是会互相影响的,子问题发生了重叠,所以这个题最关键的部分就在于一定要想到,dpij代表的是不戳破i和j,只戳破中间的气球能得到的最大值。因为边界的气球没有戳破,所以相当于我们要研究的区域被划分出来了,也就可以递归求解了。 实在是非常巧妙,必须承认想不出来。贴一个别人的代码吧。
答案:
class Solution:
def maxCoins(self, nums: List[int]) -> int:
if len(nums) == 0:
return 0
if len(nums) < 2:
return nums[0]
nums = [1] + nums + [1]
dp = [[0] * len(nums) for _ in range(len(nums))]
for i in range(len(nums) - 1, -1, -1):
for j in range(i + 2, len(nums)):
for k in range(i + 1, j):
dp[i][j] = max(dp[i][j], dp[i][k] + dp[k][j] + nums[i] * nums[k] * nums[j])
# print(dp)
return dp[0][-1]