[Leetcode] 312. Burst Balloons 解题报告
来源:互联网 发布:为什么服务器用centos 编辑:程序博客网 时间:2024/05/16 12:06
题目:
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:
(1) You may imagine nums[-1] = nums[n] = 1
. They are not real therefore you can not burst them.
(2) 0 ≤ n
≤ 500, 0 ≤ nums[i]
≤ 100
Example:
Given [3, 1, 5, 8]
Return 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
思路:
1、动态规划:动态规划是这道题目最容易想到的解。为了便于处理边界情况,我们给nums的首位分别加入1,然后定义dp[i][j]表示在区间[i,j]内的最优解。显然可以得到如下状态转移方程:dp[i][j] = max(dp[i][k - 1] + dp[k + 1][j] + nums[i - 1] * nums[k] * nums[j + 1] ),其中i <= k <= j。max函数里面的表达式表示最后爆破第k个气球所产生的收益。该算法的时间复杂度是O(n^3),空间复杂度是O(n^2)。由于dp[i][j]和区间内的所有子状态都有关,所以空间复杂度无法再次进行优化。
2、分治:我觉得虽然叫做分治,其实也算是一道DFS+记忆。也就是我们在递归求解的过程中,如果发现子问题已经被解决了,就直接利用;否则就先解决子问题。而判断子问题是否被解决的方法就是看dp[low][high]是否大于0,如果大于0,就说明已经被计算出来了,就直接利用。所以分支从时间和空间复杂度上和动态规划都一样,甚至本质都是一样的。但是由于分治涉及到了递归调用,所以在实际运行中会花费更多的时间。
代码:
1、动态规划:
class Solution {public: int maxCoins(vector<int>& nums) { if (nums.size() == 0) { return 0; } int n = nums.size(), temp = 0; nums.insert(nums.begin(), 1), nums.push_back(1); vector<vector<int>> dp(nums.size() + 1, vector<int>(nums.size() + 1, 0)); for(int len = 1; len <= n; ++len) { for(int left = 1; left + len <= n + 1; ++left) { int right = left + len - 1; for(int k = left; k <= right; ++k) { temp = nums[left - 1] * nums[k] * nums[right + 1] + dp[left][k - 1] + dp[k + 1][right]; dp[left][right] = max(temp, dp[left][right]); } } } return dp[1][n]; }};
2、分治:
class Solution {public: int maxCoins(vector<int>& nums) { if (nums.size() == 0) { return 0; } nums.insert(nums.begin(), 1), nums.push_back(1); vector<vector<int>> dp(nums.size() + 1, vector<int>(nums.size() + 1, 0)); return divide(nums, dp, 1, nums.size() - 2); }private: int divide(vector<int>& nums, vector<vector<int>>& dp, int low, int high) { if(low > high) { return 0; } if(dp[low][high] > 0) { // keypoint: the value has already been calculated return dp[low][high]; } int ret = 0; for(int i = low; i <= high; ++i) { int temp = nums[low - 1]*nums[i]*nums[high + 1] + divide(nums, dp, low, i - 1) + divide(nums, dp, i + 1, high); ret = max(ret, temp); } dp[low][high] = ret; return ret; }};
- [leetcode] 312. Burst Balloons 解题报告
- LeetCode 312. Burst Balloons 解题报告
- [Leetcode] 312. Burst Balloons 解题报告
- Burst Balloons解题报告
- leetcode 312. Burst Balloons
- [leetcode] 312. Burst Balloons
- LeetCode 312. Burst Balloons
- LeetCode 312. Burst Balloons
- leetcode.312. Burst Balloons
- 【leetcode】312. Burst Balloons
- LeetCode 312. Burst Balloons
- leetcode 312. Burst Balloons
- leetcode 312.Burst Balloons
- Leetcode-312. Burst Balloons
- 【Leetcode】312. Burst Balloons
- 【leetcode】312. Burst Balloons
- 【leetcode】312. Burst Balloons
- LeetCode 312. Burst Balloons
- python程序设计基础--函数(上)
- 数据库学习(二)
- 内核调用顺序
- Jenkins上下游jobs设置(并行、串行)
- 外星人(alien)
- [Leetcode] 312. Burst Balloons 解题报告
- scala读取HDFS上的文件,每次读取一行
- 杭电problem1005-Number Sequence
- vim 查找多个文件, 替换
- 百练_2856:计算邮资
- Docker应用示例1--使用Docker创建Web服务
- CentOS 7.0 使用iptables
- 斜率小于0的连线数量 51Nod
- spark HA 模式搭建 (详细配置)《转载》