【LeetCode】312. Burst Balloons 解题报告(Python)
作者: 负雪明烛
id: fuxuemingzhu
个人博客: http://fuxuemingzhu.cn/
题目地址: https://leetcode.com/problems/burst-balloons/description/
题目描述:
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: 167
Explanation: 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
题目大意
打气球游戏,当我们打某个位置的气球的时候,能获得它左右两个气球上的分数和自身分数的乘积。问如何打气球能获得最多的分数?可以认为最左右两边隐含着分数为1不用打破的气球。
解题方法
这个是个DP的题目,当然也可以通过记忆化搜索的方式解决。
令dfs(i, j) 和 c[i][j]是在第[i, j]闭区间上打破气球能获得最大值。那么,在其中找到一个不打破的气球k,则可以得到以下关系:
c[i][j] = max(c[i][j], self.dfs(nums, c, i, k - 1) + nums[i - 1] * nums[k] * nums[j + 1] + self.dfs(nums, c, k + 1, j))
含义是,我们找出在[i, k - 1]、[k + 1, j]闭区间打气球的分数最大值,然后会把第i - 1和第j + 1个气球保留下来,让这两个气球和第k个气球相乘,最后求三个加法。
模拟左右两边的气球的方法是直接添加上首尾各一个1,同时使用记忆化能加速不少,也为下一步的DP提供思路。
时间复杂度是O(N^2 * log(N))(不会算…),空间复杂度是O(N)。
class Solution(object):
def maxCoins(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
n = len(nums)
nums.insert(0, 1)
nums.append(1)
c = [[0] * (n + 2) for _ in range(n + 2)]
return self.dfs(nums, c, 1, n)
def dfs(self, nums, c, i, j):
if i > j: return 0
if c[i][j] > 0: return c[i][j]
if i == j: return nums[i - 1] * nums[i] * nums[i + 1]
res = 0
for k in range(i, j + 1):
res = max(res, self.dfs(nums, c, i, k - 1) + nums[i - 1] * nums[k] * nums[j + 1] + self.dfs(nums, c, k + 1, j))
c[i][j] = res
return c[i][j]
第二种解法是使用DP。
DP一般都可以通过记忆化搜索来改出来,但是我不会。。很遗憾,参考了别人的代码,还是没搞懂。。
class Solution(object):
def maxCoins(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
n = len(nums)
nums.insert(0, 1)
nums.append(1)
dp = [[0] * (n + 2) for _ in range(n + 2)]
for len_ in range(1, n + 1):
for left in range(1, n - len_ + 2):
right = left + len_ - 1
for k in range(left, right + 1):
dp[left][right] = max(dp[left][right], dp[left][k - 1] + nums[left - 1] * nums[k] * nums[right + 1] + dp[k + 1][right])
return dp[1][n]
参考资料:
http://www.cnblogs.com/grandyang/p/5006441.html
https://www.youtube.com/watch?v=z3hu2Be92UA
日期
2018 年 10 月 2 日 —— 小蓝单车莫名其妙收了我1块钱,明明每个月免费骑10次的啊!
【LeetCode】312. Burst Balloons 解题报告(Python)的更多相关文章
- 【LeetCode】452. Minimum Number of Arrows to Burst Balloons 解题报告(Python)
[LeetCode]452. Minimum Number of Arrows to Burst Balloons 解题报告(Python) 标签(空格分隔): LeetCode 题目地址:https ...
- 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] 312. Burst Balloons 打气球游戏
Given n balloons, indexed from 0 to n-1. Each balloon is painted with a number on it represented by ...
- [LeetCode] 312. Burst Balloons 爆气球
Given n balloons, indexed from 0 to n-1. Each balloon is painted with a number on it represented by ...
- 【LeetCode】120. Triangle 解题报告(Python)
[LeetCode]120. Triangle 解题报告(Python) 作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 题目地址htt ...
- LeetCode 1 Two Sum 解题报告
LeetCode 1 Two Sum 解题报告 偶然间听见leetcode这个平台,这里面题量也不是很多200多题,打算平时有空在研究生期间就刷完,跟跟多的练习算法的人进行交流思想,一定的ACM算法积 ...
- 【LeetCode】Permutations II 解题报告
[题目] Given a collection of numbers that might contain duplicates, return all possible unique permuta ...
- 【LeetCode】Island Perimeter 解题报告
[LeetCode]Island Perimeter 解题报告 [LeetCode] https://leetcode.com/problems/island-perimeter/ Total Acc ...
随机推荐
- Docker初试
1. docker是啥? 自行Google或百度去... https://yeasy.gitbooks.io/docker_practice/introduction/what.html 重要概念: ...
- fping (比ping更强大的ping工具)
Fping程序类似于ping(ping是通过ICMP(网络控制信息协议InternetControl Message Protocol)协议回复请求以检测主机是否存在).Fping与ping不同的地方 ...
- 使用Docker编译OpenResty支持国密ssl加密
编译环境 执行编译操作环境如下 #操作系统 CentOS Linux release 7.4.1708 (Core) #docker版本 Version: 19.03.5 编译过程 Dockerfil ...
- Angular @ViewChild,Angular 中的 dom 操作
Angular 中的 dom 操作(原生 js) ngAfterViewInit(){ var boxDom:any=document.getElementById('box'); boxDom.st ...
- midi的一些概念,包括一些音乐的概念
参考:http://www.yueqixuexi.com/jita/20180918205363.html https://blog.csdn.net/meicheng777/article/deta ...
- 二叉树——Java实现
1 package struct; 2 3 interface Tree{ 4 //插入元素 5 void insert(int value); 6 //中序遍历 7 void inOrder(); ...
- Linux:sqlldr命令
第一步:写一个 ctl格式的控制文件 CTL 控制文件的内容 : load data --1. 控制文件标识 infile 'xxx.txt' --2. 要导入的数据文件名 insert into t ...
- 用户创建firefox配置文件
1.打开cmd进放 firefox.exe所在的目录 如:D:\>cd D:\Mozilla Firefox 2.运行如命令:D:\Mozilla Firefox>firefox.exe ...
- java代码从出生到执行的过程浅析
阅读<深入理解java虚拟机 第二版 JVM高级特性与最佳实践> - jdk版本为1.6 1.什么是编译型语言.解释型语言 解释型语言:源代码不是直接翻译成机器语言,而是先翻译成中间代码, ...
- C# 编写一个小巧快速的 Windows 动态桌面软件
开源自己前段时间使用 C# 编写的 Windows 动态桌面软件,在接下来的博客我将描写一些技术细节和遇到的一些坑.这个软件可以把视频设置成桌面背景播放,不仅如此而且还可以把网页或一个网页文件设置成桌 ...