题目

有 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 = 315 + 358 + 138 + 181 = 167

解法

这道题没有什么奇淫巧技,刚开始很多人都会想到列举数组的全排列,然后求最大值,这种方法的复杂度会随着数组元素增加而呈指数级增长,因此不可取。

本题我们将使用动态规划来解决。

1.将下标为-1和n的元素加入新数组point中,并将nums拷贝到新数组,此时新数组大小为nums.length+2;

2.既然要我们戳破所有气球能获得的最大硬币数,那么可以规定数组dp,其中dp[i][j]代表戳破(i,j)范围内的所有气球(不包含i,j)能获得的最大硬币数,并算出推导公式;

3.推导公式:dp[i][j] = dp[i][k] + dp[k][j] + point[i]*point[k]*point[j]dp[i][k]表示戳破(i,k)范围内所有气球获得的最大金币,dp[k][j] 表示戳破(k,j)范围内所有气球获得的最大金币,point[i]*point[k]*point[j]表示最后戳破k气球获得金币;

4.遍历顺序:因为dp[i][j] 依赖于 dp[i][k]dp[k][j]的值,而dp[i][k] 在其左边,dp[k][j]在其下边,如图
所以我们采用从下往上、从左往右的遍历方法,代码如下:

class Solution {//动态规划法public int maxCoins(int[] nums) {int numLength = nums.length;//将-1和n+1下标元素加入数   组,创建新数组存储int[] point = new int[numLength+2];//给下标-1和n+1下标元素赋值point[0] = 1;point[numLength+1] = 1;//将nums数组拷贝到point数组for (int i=1;i<numLength+1;i++) {point[i] = nums[i-1];}//dp[i][j] 代表 戳破i~j之间的气球(不包含i,j)获得的最大金币int[][] dp = new int[numLength+2][numLength+2];//确定i,j的遍历顺序和方向//二维数组从下到上、从左到右遍历,确保dp[i][k]和dp[k][j]有值for (int i=numLength;i>=0;i--) {for (int j=i+1;j<=numLength+1;j++) {//逐个k尝试,找出使dp[i][j]最大的k值for (int k=i+1;k<=j-1;k++) {dp[i][j] = Math.max(dp[i][k] + dp[k][j] + point[i]*point[k]*point[j],dp[i][j]);}}}//戳破0~numLength+1之间的气球,就是nums数组中全部气球return dp[0][numLength+1];}
}

动态规划套路解决戳气球问题相关推荐

  1. LeetCode·312.戳气球·动态规划

    312.戳气球 题目 示例 思路 首先必须要说明,这个题目的状态转移方程真的比较巧妙,所以说如果你看了题目之后完全没有思路恰恰是正常的.虽然最优答案不容易想出来,但基本的思路分析是我们应该力求做到的. ...

  2. 经典动态规划:戳气球问题

    点击上方蓝字设为星标 东哥带你手把手撕力扣~ 作者:labuladong   公众号:labuladong 若已授权白名单也必须保留以上来源信息 今天我们要聊的这道题「Burst Balloon」和之 ...

  3. 算法学习笔记——动态规划:戳气球

    LeetCode 312. 戳气球 数组 nums 中,保存了每个气球上的数字,戳破一个气球,得分是nums[i - 1] * nums[i] * nums[i + 1](若越界,认为两个边界上有数值 ...

  4. Leetcode 312. 戳气球

    题目 首先必须要说明,这个题目的状态转移方程真的比较巧妙,所以说如果你看了题目之后完全没有思路恰恰是正常的.虽然最优答案不容易想出来,但基本的思路分析是我们应该力求做到的.所以本文会先分析一下常规思路 ...

  5. 【LeetCode】312. 戳气球

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

  6. LeetCode312 戳气球

    回溯思想 很显然涉及求最值,没有任何奇技淫巧,一定是穷举所有可能的结果,然后对比得出最值 所以说,只要遇到求最值的问题,首先要思考的就是:如何穷举所有可能的结果 穷举主要有两种算法:就是回溯算法和动态 ...

  7. 312. Burst Balloons 戳气球

    Title 有 n 个气球,编号为0 到 n-1,每个气球上都标有一个数字,这些数字存在数组 nums 中. 现在要求你戳破所有的气球.如果你戳破气球 i ,就可以获得 nums[left] * nu ...

  8. 动态规划套路:最大子数组和

    动态规划套路:最大子数组和 文章目录 动态规划套路:最大子数组和 一.题目描述 二.分析 一.题目描述 这次看一个简答的题: 二.分析 这道题比较简单,主要是回顾动态 规划的解法! 其实第一次看到这道 ...

  9. LeetCode312:戳气球

    要求 有 n 个气球,编号为0 到 n - 1,每个气球上都标有一个数字,这些数字存在数组 nums 中. 现在要求你戳破所有的气球.戳破第 i 个气球,你可以获得 nums[i - 1] * num ...

最新文章

  1. Cisco路由器——Console线的接法
  2. python selenium_Python+selenium自动化测试
  3. VB6实现的自动停靠窗体
  4. 面试准备——Java回顾:基础编程(基本语法、面向对象、异常处理)
  5. android 初始化变量,变量初始化 - Android Studio
  6. 学习OpenCV(2)OpenCV初探-2
  7. 集成电路芯片半导体中英文对照术语词汇表
  8. windows下如何创建bat文件
  9. 删除ttf字体文件中无用文字
  10. mysql导出到excel方法汇总
  11. 远程访问openwrt路由器+配置动态DNS
  12. 算法之美_源码公布(1)
  13. Seurat | 不同单细胞转录组的整合方法
  14. 关灯后灯常亮、微亮、闪烁——多种原因分析
  15. 小米面试offer加油
  16. 小学生学习Python的步骤和学习周期之我见
  17. ubuntu22.04 安装优化(主题,软件,换源,插件扩展)
  18. 惊闻高中同学因公殉职
  19. 如何在万米高空畅享5G?
  20. 云计算基础设施软件厂商简介

热门文章

  1. 【Hibernate】Hql语句in中带参数的写法
  2. mysql 删除表数据但不删除表结构SQL语句
  3. 生成50道100以内加法/减法算式的习题_软件构造_羊卓的杨
  4. 医疗器械设备产品展示小程序
  5. C++读入txt,写入txt,循环读入txt,循环写入txt
  6. 查看电脑配置指令大全
  7. ICESat-2—用单光子激光雷达从太空测量地球表层高度
  8. 那时我还年轻,也想不到以后会怎么样,就是想要呆在机房里,为了做出题目这样纯粹的感动而活下去。
  9. 如何保护个人隐私和数据安全
  10. Hexo+yilia添加helper-live2d插件宠物动画,很好玩的哦~~