|
30鱼币
本帖最后由 zltzlt 于 2019-11-9 13:28 编辑
今天的题目:
有 n 个气球,编号为 0 到 n-1,每个气球都有一个分数,存在 nums 数组中。每次吹 j 号气球可以得到的分数为 nums[left] * nums[j] * nums[right],left 和 right 分别表示 j 号气球相邻的两个气球。当 j 号气球被吹爆后,其左右两气球即为相邻。要求返回吹爆所有气球得到最多的分数。
注意:nums 不为空。
样例 1:
输入:[4, 1, 5, 10]
输出:270
解释:
nums = [4, 1, 5, 10] 吹爆 1,得分 4 * 1 * 5 = 20
nums = [4, 5, 10] 吹爆 5, 得分 4 * 5 * 10 = 200
nums = [4, 10] 吹爆 4,得分 1 * 4 * 10 = 40
nums = [10] 吹爆 10,得分 1 * 10 * 1 = 10
总得分为 20 + 200 + 40 + 10 = 270。 样例 2:
输入:[3,1,5]
输出:35
解释:
nums = [3, 1, 5] 吹爆 1,得分 3 * 1 * 5 = 15
nums = [3, 5] 吹爆 3,得分 1 * 3 * 5 = 15
nums = [5] 吹爆 5,得分 1 * 5 * 1 = 5
总得分为 15 + 15 + 5 = 35。
 欢迎大家一起答题! 
- """
- 我的理解:
- l-----m-----r
- | | |
- nums: [3, 1, 5, 8] -> new_nums: [1, 3, 1, 5, 8, 1]
- 对于上方 new_nums 这种情况
- => dp[l][r] = dp[l][m] + dp[m][r] + new_nums[l] * new_nums[m] * new_nums[r]
- dp[l][r]: 吹爆 l 与 r 之间的气球,但不包括 l 和 r;不同的 m 可能有不同的 dp[l][r]
- """
- def f271(nums):
- new = [1] + [i for i in nums if i] + [1] # 删去对结果没有影响的 0,并补齐两侧默认的 1
- n = len(new)
- dp = [[0]*n for _ in range(n)]
- for gap in range(2, n): # 从 3 个一组,到 n 个一组
- for l in range(n - gap):
- r = l + gap
- tmp = new[l] * new[r] # 避免重复计算
- for m in range(l + 1, r):
- dp[l][r] = max(dp[l][r], dp[l][m] + dp[m][r] + tmp * new[m])
- return dp[0][-1]
复制代码
|
|