LeetCode312. Burst Balloons
Given n balloons, indexed from 0 to n-1. Each balloon is painted with a number on it represented by array nums. You are asked to burst all the balloons. If the you burst balloon i you will get nums[left] * nums[i] * nums[right] coins. Here left and right are adjacent indices of i. After the burst, the left and right then becomes adjacent.
Find the maximum coins you can collect by bursting the balloons wisely.
Note:
- You may imagine
nums[-1] = nums[n] = 1. They are not real therefore you can not burst them. - 0 ≤
n≤ 500, 0 ≤nums[i]≤ 100
Example:
Input:[3,1,5,8]
Output:167nums = [3,1,5,8] --> [3,5,8] --> [3,8] --> [8] --> []
Explanation:
coins = 3*1*5 + 3*5*8 + 1*3*8 + 1*8*1 = 167
思路
解法有backtrack和dp两种,首先还是来分析题目。
这题的要素有:n 个气球,从0到n-1编号,每个气球都标记了一个硬币数字。戳爆其中一个会得到指定的coings,与相邻的两个数字的乘积是所获得的硬币数。那么如何确定戳爆顺序使得获得的硬币数目最大?难点在于不同的戳爆顺序会相互影响。
从最后戳爆的气球位置入手,如果最后戳爆的气球是位置i上的气球,那么可以肯定的是在它之前的 0~i-1 位置上的气球肯定被戳爆了,i+1到n-1位置上的气球也被戳爆了。递归遍历所有的i即可。
public int maxCoins(int[] iNums) {
int[] nums = new int[iNums.length + 2]; // 构造新数组,方便计算
int n = 1;
for (int x : iNums) if (x > 0) nums[n++] = x;
nums[0] = nums[n++] = 1; // 这里一直用n++是因为要忽视iNums的0,这样n最后不一定等于iNum的长度
int[][] memo = new int[n][n]
return burst(memo, nums, 0, n - 1); // 从1到n-1位置上搜索,即left+1~right,之所以n-1是因为上面的n++使得n到了末尾1的后一位
}
public int burst(int[][] memo, int[] nums, int left, int right) {
if (left + 1 == right) return 0; // 如果left+1==right,因为是从left+1到right-1处遍历的。遍历结束,直接返回
if (memo[left][right] > 0) return memo[left][right]; // 如果已计算过,则不需再次计算
int ans = 0;
for (int i = left + 1; i < right; ++i) // 初始从left+1到right-1,对应起来正好是iNums中的0~n-1
ans = Math.max(ans, nums[left] * nums[i] * nums[right]
+ burst(memo, nums, left, i) + burst(memo, nums, i, right));
memo[left][right] = ans;
return ans;
}
DP解法如下:
public int maxCoins(int[] iNums) {
int[] nums = new int[iNums.length + 2];
int n = 1;
for (int x : iNums) if (x > 0) nums[n++] = x;
nums[0] = nums[n++] = 1;
int[][] dp = new int[n][n];
// k表示计算步长,从right=left+2开始。因为i从left+1到right-1遍历,所以一开始只计算left和right之间只隔了一位的情况
for (int k = 2; k < n; ++k)
for (int left = 0; left < n - k; ++left) {
int right = left + k;
for (int i = left + 1; i < right; ++i) // 在子问题dp[left][right]下,遍历每个可能的最后引爆的气球,以求出子问题的最优解
dp[left][right] = Math.max(dp[left][right],
nums[left] * nums[i] * nums[right] + dp[left][i] + dp[i][right]); // 左边界是left,右边界是right
}
return dp[0][n - 1];
}
LeetCode312. Burst Balloons的更多相关文章
- [LeetCode] Burst Balloons (Medium)
Burst Balloons (Medium) 这题没有做出来. 自己的思路停留在暴力的解法, 时间复杂度很高: 初始化maxCount = 0. 对于当前长度为k的数组nums, 从0到k - 1逐 ...
- 动态规划-Burst Balloons
Burst Balloons Given n balloons, indexed from 0 to n-1. Each balloon is painted with a number on it ...
- LeetCode 312. Burst Balloons(戳气球)
参考:LeetCode 312. Burst Balloons(戳气球) java代码如下 class Solution { //参考:https://blog.csdn.net/jmspan/art ...
- LN : leetcode 312 Burst Balloons
lc 312 Burst Balloons 312 Burst Balloons Given n balloons, indexed from 0 to n-1. Each balloon is pa ...
- 贪心:leetcode 870. Advantage Shuffle、134. Gas Station、452. Minimum Number of Arrows to Burst Balloons、316. Remove Duplicate Letters
870. Advantage Shuffle 思路:A数组的最大值大于B的最大值,就拿这个A跟B比较:如果不大于,就拿最小值跟B比较 A可以改变顺序,但B的顺序不能改变,只能通过容器来获得由大到小的顺 ...
- 【LeetCode】452. Minimum Number of Arrows to Burst Balloons 解题报告(Python)
[LeetCode]452. Minimum Number of Arrows to Burst Balloons 解题报告(Python) 标签(空格分隔): LeetCode 题目地址:https ...
- [Swift]LeetCode312. 戳气球 | Burst Balloons
Given n balloons, indexed from 0 to n-1. Each balloon is painted with a number on it represented by ...
- [LeetCode] Minimum Number of Arrows to Burst Balloons 最少数量的箭引爆气球
There are a number of spherical balloons spread in two-dimensional space. For each balloon, provided ...
- [LeetCode] Burst Balloons 打气球游戏
Given n balloons, indexed from 0 to n-1. Each balloon is painted with a number on it represented by ...
随机推荐
- Unity3D for VR 学习(9): Unity Shader 光照模型 (illumination model)
关于光照模型 所谓模型,一般是由学术算法发起, 经过大量实际数据验证而成的可靠公式 现在还记得2009年做TD-SCDMA移动通信算法的时候,曾经看过自由空间传播模型(Free space propa ...
- 《Linux内核设计与实现》第1、2章读书笔记
第一章 1.Unix内核特点 十分简洁:仅提供几百个系统调用并且有明确的目的: 在Unix中,大部分东西都被(或者正致力于)被当做文件对待: Unix内核即相关系统工具软件都是用C语言编写的,这使得系 ...
- acid(数据库事务正确执行的四个基本要素的缩写)
ACID,指数据库事务正确执行的四个基本要素的缩写.包含:原子性(Atomicity).一致性(Consistency).隔离性(Isolation).持久性(Durability).一个支持事务(T ...
- 谷哥的小弟学前端(02)——HTML常用标签(2)
探索Android软键盘的疑难杂症 深入探讨Android异步精髓Handler 详解Android主流框架不可或缺的基石 站在源码的肩膀上全解Scroller工作机制 Android多分辨率适配框架 ...
- OpenCV图像变换(仿射变换与透视变换)
仿射变换(affine transform)与透视变换(perspective transform)在图像还原.图像局部变化处理方面有重要意义.通常,在2D平面中,仿射变换的应用较多,而在3D平面中, ...
- django 配置xamdin遇到的坑
是在 Django==1.11.7 这个版本下配置的,需要说明的是,不是通过pip install xadmin方式安装的 在github上下载的xadmin源码包,需要在项目的根目录下创建extra ...
- Ubuntu+NDK编译openssl
为了Android上使用libcurl且支持HTTPS协议,需要依赖openssl,因此先来了解一下如何编译OpenSSL1.编译ARM下的共享库(默认的)我使用的是guardianproject的o ...
- Java设计模式の迭代器模式
迭代器模式定义 迭代器模式(Iterator),提供一种方法顺序访问一个聚合对象中的各种元素,而又不暴露该对象的内部表示. 迭代器模式的角色构成 (1)迭代器角色(Iterator):定义遍历元素所需 ...
- python requests https 访问出错
错误提示: /usr/local/lib/python2.7/site-packages/requests/packages/urllib3/util/ssl_.py:100: InsecurePla ...
- ios 字符串截取
NSString *str = @"my name is jiemu"; 1.从第三个字符开始,截取长度为4的字符串 NSString *str2 = [str substring ...