Title

有 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

示例:

输入: [3,1,5,8]
输出: 167
解释: nums = [3,1,5,8] --> [3,5,8] -->   [3,8]   -->  [8]  --> []coins =  3*1*5      +  3*5*8    +  1*3*8      + 1*8*1   = 167

动态规划

为了方便处理,我们对 nums 数组稍作处理,将其两边各加上题目中假设存在的 nums[−1] 和 nums[n] ,并保存在 val 数组中,即 val[i]=nums[i−1] 。之所以这样处理是为了处理 nums[−1] ,防止下标越界。

逆向思维,戳气球会导致两个气球从不相邻变成相邻,很难处理,我们倒过来看,将全过程看作是每次添加一个气球。

令 dp[i][j] 表示填满开区间 (i,j) 能得到的最多硬币数,那么边界条件是 i≥j−1,此时有 dp[i][j]=0。

可以写出状态转移方程:

dp[i][j]={maxk=i+1j−1val[i]×val[k]×val[j]+dp[i][k]+dp[k][j],i<j−10,i>=j−1dp[i][j]=\begin{cases} max^{j-1}_{k=i+1}val[i]×val[k]×val[j]+dp[i][k]+dp[k][j],\quad i<j-1 \\\\ 0,\quad i>=j-1 \end{cases}dp[i][j]=⎩⎪⎨⎪⎧​maxk=i+1j−1​val[i]×val[k]×val[j]+dp[i][k]+dp[k][j],i<j−10,i>=j−1​

最终答案即为 dp[0][n+1]。实现时要注意到动态规划的次序。

Code

 def maxCoins(self, nums: List[int]) -> int:length, val = len(nums), [1] + nums + [1]dp = [[0] * (length + 2) for _ in range(length + 2)]for i in range(length - 1, -1, -1):for j in range(i + 2, length + 2):for k in range(i + 1, j):total = val[i] * val[k] * val[j]total += dp[i][k] + dp[k][j]dp[i][j] = max(dp[i][j], total)return dp[0][length + 1]

复杂度分析

时间复杂度:O(n3),其中 n 是气球数量。状态数为 n2,状态转移复杂度为 O(n),最终复杂度为 O(n2×n)=O(n3)。

空间复杂度:O(n2),其中 n 是气球数量。

312. Burst Balloons 戳气球相关推荐

  1. 力扣312题:戳气球

    力扣312题:戳气球 题目描述 有 n 个气球,编号为0 到 n - 1,每个气球上都标有一个数字,这些数字存在数组 nums 中. 现在要求你戳破所有的气球.戳破第 i 个气球,你可以获得 nums ...

  2. 312. Burst Balloons

    题目: Given n balloons, indexed from 0 to n-1. Each balloon is painted with a number on it represented ...

  3. LeetCode 312. Burst Balloons(戳气球)

    原题网址:https://leetcode.com/problems/burst-balloons/ Given n balloons, indexed from 0 to n-1. Each bal ...

  4. leetcode 312. Burst Balloons | 312. 戳气球(暴力递归->DP)

    题目 https://leetcode.com/problems/burst-balloons/ 题解 好久不 DP 了,DP 一下吧,结果被坑了很久,看了答案. 递归的时候,我知道分成L,R两边,但 ...

  5. [Leetcode][第312题][JAVA][戳气球][动态规划][记忆化搜索]

    [问题描述][困难] [解答思路] 1. 记忆化搜索 时间复杂度:O(n^3) 空间复杂度:O(n^2) class Solution {public int[][] rec;public int[] ...

  6. LeetCode 312. Burst Balloons

    一看就是DP题,但是递推公式比较难想.为了简化问题,给 nums 开始和最后都加上1. 记 dp[i][j] 表示 nums[i~j] 能得到的最大coin. k 表示保留着的气球, dp[i][j] ...

  7. 【Leetcode】312. Burst Balloons

    第一种思路可以采用backtracking.把一个list传递下去,每一步可以选择任意一个删除,然后再递归处理下一个,比较简单. public int maxCoins1(int[] nums) {i ...

  8. 【LeetCode】312. 戳气球

    312. 戳气球(困难) 解法一:动态规划 首先看一个区间: 区间(i,j) 是一个开区间,因为我们只能戳爆 i 和 j 之间的气球,不能戳爆索引为 i 和 j 的气球. 我们不妨考虑该区间内被戳爆的 ...

  9. Leetcode.312 戳气球

    题目链接 Leetcode.312 戳气球 题目描述 有 n个气球,编号为0到 n - 1,每个气球上都标有一个数字,这些数字存在数组 nums中. 现在要求你戳破所有的气球.戳破第 i 个气球,你可 ...

最新文章

  1. ClassLoader的双亲委派模型
  2. python使用openpyxl读取数据_Python-openpyxl读取和写入数据1
  3. Hibernate关联关系映射实例速查
  4. 【错误记录】Android 应用 release 打包报错处理 ( 关闭语法检查 | 日志处理 | release 配置 )
  5. JS 获取指定时间的时间戳(兼容各个浏览器)
  6. 完美解答35K月薪的MySQL面试题(一)MySQL是如何存储数据的
  7. 《***测试实践指南》D03
  8. 最全的正则表达式大全
  9. qt sizePolicy属性
  10. 音视频开发(15)---IPC+NVR+路由器+ffmpeg+nginx实现网页/Android/IOS的HLS直播
  11. 共享单车变“私有”、被毁、被盗:用户们都看不下去了,举报!
  12. 梯度下降优化算法综述
  13. Spring获取外网IP
  14. talfta---动态故障树分析软件产品介绍
  15. html5课程总结500字,高中月考总结与反思500字(精选5篇)
  16. ipad/ios按钮背景颜色为渐变色?去除iOS按钮渐变色
  17. java中讲讲DataOutputStream的用法,举例?
  18. 常见的几种协同设计平台对比分析
  19. 联想收购方正,不是不可能
  20. 利用pot播放器将视频的音频文件抽离。

热门文章

  1. primefaces 查询 点击按钮 加载 动画 ajax loader
  2. 如何使用matplotlib绘制一个函数的图像
  3. 【★★★★★模板专区★★★★★】
  4. oracle查询使用or,查询视图,使用or就用不上索引
  5. js修改style中某个属性_JS 和 CSS 交互的 5 种方法
  6. mysql入门简历_MySQL(一)简介与入门
  7. springboot 拦截器_Spring Boot入门系列(十)如何使用拦截器,一学就会!
  8. linux字符设备移动硬盘,Red Hat Enterprise Linux 7.5挂载NTFS移动硬盘
  9. Java黑皮书课后题第5章:*5.18(使用循环语句打印4个图案)使用嵌套的循环语句,编写4个独立的程序打印下面的图案
  10. 3-5 获取命令行参数