【重拾算法~Leetcode每日一题】312. 戳气球(难度:困难)

312. 戳气球
有 n 个气球,编号为0 到 n-1,每个气球上都标有一个数字,这些数字存在数组 nums 中。
现在要求你戳破所有的气球。如果你戳破气球 i ,就可以获得 nums[left] * nums[i] * nums[right] 个硬币。 这里的 left 和 right 代表和 i 相邻的两个气球的序号。注意当你戳破了气球 i 后,气球 left 和气球 right 就变成了相邻的气球。
求所能获得硬币的最大数量。
说明:
你可以假设 nums[-1] = nums[n] = 1,但注意它们不是真实存在的所以并不能被戳破。
0 ≤ n ≤ 500, 0 ≤ nums[i] ≤ 100

这一题的主要难点在于动态规划的状态转移方程,如果用暴力算法,时间复杂度为O(n!),当n=500时,可想而知肯定超时,随后我就想到了dp,但是我不知道怎么状态转移,因为每戳破一个气球,原气球的排列顺序就会改变,因此需要换一个思路,在膜拜完题解大佬的思路后,我尝试着用大佬的思路解题,思路:

  1. 假设最后留下了一个气球,可以最大化硬币,气球的位置为k
  2. 设F [ i ] [ j ] 为戳破 i+1 ~ j-1 所有气球的最大收益
  3. F [ i ] [ j ] = max(F[ i ] [ k ] + F[ k ] [ j ] + nums[ i ] * nums [ j ] * nums [ k ])
  4. 也就是说在i+1~j-1假设留下一个气球,求留下哪一个能使收益最大化

解决了状态转移方程,问题就解决了一大半,我们只需要考虑边界问题

  1. 当 i > j 时, 无意义
  2. 当 i = j 或 i = j - 1 时 ,无可戳破的气球,F[ i ] [ j ] = 0

k的取值范围很好解决,应该在 i+1 ~ j-1 这个范围
那么怎么循环i和j呢?
由状态转移方程可知,如果想知道 F [ i ] [ j ] ,那么从矩阵的 i行 j列 往下往左都应该是已知的,你可以斜着循环也可以从最后一行往第一行循环,最后只要返回F [ 0 ] [ -1 ] 即可

class
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值