300-700题红题第二题

文章讲述了如何利用动态规划策略解决一个关于戳破气球获取最大分数的问题。在气球序列两端添加分数为1的气球,然后按特定顺序遍历,计算不同子长度内最后一个爆破气球带来的最大收益。动态规划数组dp用于存储子序列的最大分数。
摘要由CSDN通过智能技术生成

题目链接:312. 戳气球

动态规划

这个题的大概解决办法是,在整个气球长度内选取一段子长度,然后在子长度中选择一个最后爆破的气球,因为是最后爆破的所以获得的收益是已知的:
气球自己的分数 × \times × 子长度前一个气球的分数 × \times × 子长度后一个气球的分数。
而此时子长度被这个气球分为两段,这两段右是两个子长度,又可以继续分以此的到这段子长度的最大分数。

边界问题

因为爆破头尾气球的时候,他的左右是用1来代替的,所以我们可以在nums左右加上一个分数是1的气球。
nums = [3,1,5,8] 变成 [1,3,1,5,8,1]

遍历顺序

这个遍历顺序很神奇,我们要思考一下的到最后结果的顺序,从最终长度n出发,遍历最后一个爆破的气球,然后处理两边的子长度,而子长度的范围是0到n-1,选择能给出最大分数的最后一个爆破气球。
所以dp[i][j] = 长度为i,起点为j的子长度的最大分数。
而遍历顺序为先遍历子长度的长度i,再遍历子长度在原本长度里的起点j,最后遍历最后一个爆破的气球的位置k选取最大值,填入dp[i][j]。

这里数组内的位置还是要好好写一下的,不然容易乱。

class Solution:
    def maxCoins(self, nums: List[int]) -> int:
        nums = [1] + nums + [1]
        n = len(nums)
        dp = [[0]*(n) for _ in range(n)]
        for i in range(1,(n-1)): #当前处理的气球长度
            for j in range(1,(n-i)): #当前处理的气球长度的起点
                for k in range(j,j+i): #最后爆掉的气球
                    last = nums[k] * nums[j-1] * nums[i+j]
                    front = dp[k-j][j]
                    later = dp[i+j-1-k][k+1]
                    dp[i][j] = max(dp[i][j], last + front + later)
        return max(dp[-2])
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值