作者: 负雪明烛
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)的更多相关文章

  1. 【LeetCode】452. Minimum Number of Arrows to Burst Balloons 解题报告(Python)

    [LeetCode]452. Minimum Number of Arrows to Burst Balloons 解题报告(Python) 标签(空格分隔): LeetCode 题目地址:https ...

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

    参考:LeetCode 312. Burst Balloons(戳气球) java代码如下 class Solution { //参考:https://blog.csdn.net/jmspan/art ...

  3. 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 ...

  4. [LeetCode] 312. Burst Balloons 打气球游戏

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

  5. [LeetCode] 312. Burst Balloons 爆气球

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

  6. 【LeetCode】120. Triangle 解题报告(Python)

    [LeetCode]120. Triangle 解题报告(Python) 作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 题目地址htt ...

  7. LeetCode 1 Two Sum 解题报告

    LeetCode 1 Two Sum 解题报告 偶然间听见leetcode这个平台,这里面题量也不是很多200多题,打算平时有空在研究生期间就刷完,跟跟多的练习算法的人进行交流思想,一定的ACM算法积 ...

  8. 【LeetCode】Permutations II 解题报告

    [题目] Given a collection of numbers that might contain duplicates, return all possible unique permuta ...

  9. 【LeetCode】Island Perimeter 解题报告

    [LeetCode]Island Perimeter 解题报告 [LeetCode] https://leetcode.com/problems/island-perimeter/ Total Acc ...

随机推荐

  1. kubectl logs查看日志时出现failed to create fsnotify watcher: too many open files

    因为系统默认的 fs.inotify.max_user_instances=128 太小,在查看日志的pod所在节点重新设置此值: 临时设置 sudo sysctl fs.inotify.max_us ...

  2. JSP内置对象之out对象

    一.       JSP内置对象的概述     由于JSP使用java作为脚本语言,所以JSP将具有强大的对象处理能力,并且可以动态地创建Web页面内容.但Java语法在使用一个对象前,需要先实例化这 ...

  3. 19. awk 命令详解

    awk是一个强大的文本分析工具,相对于grep的查找,sed的编辑,awk在其对数据分析并生成报告时,显得尤为强大.简单来说awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行各 ...

  4. Flink(八)【Flink的窗口机制】

    目录 Flink的窗口机制 1.窗口概述 2.窗口分类 基于时间的窗口 滚动窗口(Tumbling Windows) 滑动窗口(Sliding Windows) 会话窗口(Session Window ...

  5. flink-----实时项目---day06-------1. 获取窗口迟到的数据 2.双流join(inner join和left join(有点小问题)) 3 订单Join案例(订单数据接入到kafka,订单数据的join实现,订单数据和迟到数据join的实现)

    1. 获取窗口迟到的数据 主要流程就是给迟到的数据打上标签,然后使用相应窗口流的实例调用sideOutputLateData(lateDataTag),从而获得窗口迟到的数据,进而进行相关的计算,具体 ...

  6. 大数据学习day32-----spark12-----1. sparkstreaming(1.1简介,1.2 sparkstreaming入门程序(统计单词个数,updateStageByKey的用法,1.3 SparkStreaming整合Kafka,1.4 SparkStreaming获取KafkaRDD的偏移量,并将偏移量写入kafka中)

    1. Spark Streaming 1.1 简介(来源:spark官网介绍) Spark Streaming是Spark Core API的扩展,其是支持可伸缩.高吞吐量.容错的实时数据流处理.Sp ...

  7. set、multiset深度探索

    set/multiset的底层是rb_tree,因此它有自动排序特性.set中的元素不允许重复必须独一无二,key与value值相同,multiset中的元素允许重复. set的模板参数key即为关键 ...

  8. 栈常考应用之括号匹(C++)

    思路在注释里.还是使用链栈的API,为啥使用链栈呢,因为喜欢链栈. //header.h #pragma once #include<iostream> using namespace s ...

  9. 设置linux下oracle开机自启动

    1.修改配置文件,vi /etc/oratab orcl:/u01/app/oracle/product/11.2.0/db_1:Y 2.创建启动文件,/etc/init.d/ #!/bin/sh # ...

  10. 数据源(Data Source

    数据源(Data Source)顾名思义,数据的来源,是提供某种所需要数据的器件或原始媒体.在数据源中存储了所有建立数据库连接的信息.就像通过指定文件名称可以在文件系统中找到文件一样,通过提供正确的数 ...