当前位置:   article > 正文

【重拾算法~Leetcode每日一题】312. 戳气球(难度:困难)_每一回合都会有n个气球

每一回合都会有n个气球

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
    声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小蓝xlanll/article/detail/717777
    推荐阅读
    相关标签
      

    闽ICP备14008679号