[算法分析与设计] leetcode 每周一题: 312. Burst Balloons
2017-12-02 12:34
399 查看
题目链接:
312. Burst Balloons
题目大意:
给定 n 个气球, 序号为 1 到 n-1, 每个气球又对应一个分值, 分值用长度为 n 的数组 nums 表示 ; 现要求逐个打爆所有气球, 而每打爆一个序号为 i 的气球, 就可以得到 nums[left] * num[i] * nums[right] 的分值(即
coins), 其中 nums[left], nums[right] 分别表示与该气球相邻的两边的气球所对应的分值, 且该气球被打爆了之后, 就将其从序列中(气球序列 和 他们对应的分值的序列 都是)移除, 故 left, right 将会变成相邻项 ;
假设 nums[-1] = nums
= 1 ;
假设 0 <= n <= 500, 且 0 <= nums[i] <= 100 ;
例如: 给定: nums 为 [3, 1, 5, 8], 则输出应为:
167 ; ( 3*1*5 + 3*5*8 + 3*8 + 8 = 167 )
解题过程:
(1) 我一开始很单纯地觉得 每次取(除了两边端点处的气球外)分值最小的气球来打爆(若有同分/相邻/... 的情况另加判断) 的方式就可以了, 后来做了好久才发现不妥, 毕竟这样的朴素做法很容易就会浪费了极大值的价值 ;
(2) 后来(不加证明, 就随便想)想过几种方案, 发觉均有缺陷, 这点上一般可以简单地取极端情况验证 ;
(3) 然后联想到可能需要 "穷举式" 解决, 加上输入数据量确实颇小, 于是考虑动态规划, ... 然后为了验证想法, 就直接去 leetcode 上的 discussion 版块上看了下, 想法得以验证, 还顺便看到了答案 ... ( 帖子地址 )
; (
(4) 答案的思路理解起来不难..., 这种 取样 处理的模式, 可以考虑针对每次所取的点作分割, 同时要注意到这里只要将 取样点 假设为要最后一个打爆的气球的话 其两边的 子序列 间是不会互相影响的(原序列中两端的分值为 1 的气球显然是不能打爆的, 而子序列中的两端的气球与
取样点气球 的交集又只有在(假设)打爆 取样点气球 的时候), 所以子序列间打爆气球的顺序就不重要了, 同时, 显然必然会存在这么一个要最后才打爆的气球 ;
代码如下:
Runtime: 9 ms
题目链接:
312. Burst Balloons
题目大意:
给定 n 个气球, 序号为 1 到 n-1, 每个气球又对应一个分值, 分值用长度为 n 的数组 nums 表示 ; 现要求逐个打爆所有气球, 而每打爆一个序号为 i 的气球, 就可以得到 nums[left] * num[i] * nums[right] 的分值(即
coins), 其中 nums[left], nums[right] 分别表示与该气球相邻的两边的气球所对应的分值, 且该气球被打爆了之后, 就将其从序列中(气球序列 和 他们对应的分值的序列 都是)移除, 故 left, right 将会变成相邻项 ;
假设 nums[-1] = nums
= 1 ;
假设 0 <= n <= 500, 且 0 <= nums[i] <= 100 ;
例如: 给定: nums 为 [3, 1, 5, 8], 则输出应为:
167 ; ( 3*1*5 + 3*5*8 + 3*8 + 8 = 167 )
解题过程:
(1) 我一开始很单纯地觉得 每次取(除了两边端点处的气球外)分值最小的气球来打爆(若有同分/相邻/... 的情况另加判断) 的方式就可以了, 后来做了好久才发现不妥, 毕竟这样的朴素做法很容易就会浪费了极大值的价值 ;
(2) 后来(不加证明, 就随便想)想过几种方案, 发觉均有缺陷, 这点上一般可以简单地取极端情况验证 ;
(3) 然后联想到可能需要穷举式解决, 加上输入数据量确实颇小, 于是考虑动态规划, ... 然后为了验证想法, 就直接去 leetcode 上的 discussion 版块上看了下, 想法得以验证, 还顺便看到了答案 ... ( 帖子地址 )
;
(4) 答案的思路理解起来不难..., 这种 取样 处理的模式, 可以考虑针对每次所取的点作分割, 同时要注意到这里只要将 取样点 假设为要最后一个打爆的气球的话 其两边的 子序列 间是不会互相影响的(原序列中两端的分值为 1 的气球显然是不能打爆的, 而子序列中的两端的气球与
取样点气球 的交集又只有在(假设)打爆 取样点气球 的时候), 所以子序列间打爆气球的顺序就不重要了, 同时, 显然必然会存在这么一个要最后才打爆的气球 ;
代码如下:
Runtime: 9 ms
312. Burst Balloons
题目大意:
给定 n 个气球, 序号为 1 到 n-1, 每个气球又对应一个分值, 分值用长度为 n 的数组 nums 表示 ; 现要求逐个打爆所有气球, 而每打爆一个序号为 i 的气球, 就可以得到 nums[left] * num[i] * nums[right] 的分值(即
coins), 其中 nums[left], nums[right] 分别表示与该气球相邻的两边的气球所对应的分值, 且该气球被打爆了之后, 就将其从序列中(气球序列 和 他们对应的分值的序列 都是)移除, 故 left, right 将会变成相邻项 ;
假设 nums[-1] = nums
= 1 ;
假设 0 <= n <= 500, 且 0 <= nums[i] <= 100 ;
例如: 给定: nums 为 [3, 1, 5, 8], 则输出应为:
167 ; ( 3*1*5 + 3*5*8 + 3*8 + 8 = 167 )
解题过程:
(1) 我一开始很单纯地觉得 每次取(除了两边端点处的气球外)分值最小的气球来打爆(若有同分/相邻/... 的情况另加判断) 的方式就可以了, 后来做了好久才发现不妥, 毕竟这样的朴素做法很容易就会浪费了极大值的价值 ;
(2) 后来(不加证明, 就随便想)想过几种方案, 发觉均有缺陷, 这点上一般可以简单地取极端情况验证 ;
(3) 然后联想到可能需要 "穷举式" 解决, 加上输入数据量确实颇小, 于是考虑动态规划, ... 然后为了验证想法, 就直接去 leetcode 上的 discussion 版块上看了下, 想法得以验证, 还顺便看到了答案 ... ( 帖子地址 )
; (
(4) 答案的思路理解起来不难..., 这种 取样 处理的模式, 可以考虑针对每次所取的点作分割, 同时要注意到这里只要将 取样点 假设为要最后一个打爆的气球的话 其两边的 子序列 间是不会互相影响的(原序列中两端的分值为 1 的气球显然是不能打爆的, 而子序列中的两端的气球与
取样点气球 的交集又只有在(假设)打爆 取样点气球 的时候), 所以子序列间打爆气球的顺序就不重要了, 同时, 显然必然会存在这么一个要最后才打爆的气球 ;
代码如下:
class Solution { public: int maxCoins(vector<int> & nums) { vector<int> numbers; numbers.push_back(1); for (auto i : nums) { if (i > 0) { numbers.push_back(i); } } numbers.push_back(1); const auto n = numbers.size(); vector< vector<int> > maxCoins; maxCoins.resize(n); for (auto & v : maxCoins) { v.resize(n); } for (size_t k = 2; k < n; k++) { for (size_t left = 0; left < n - k; left++) { auto right = left + k; for (auto i = left + 1; i < right; i++) { maxCoins[left][right] = max( maxCoins[left][right], numbers[left] * numbers[i] * numbers[right] + maxCoins[left][i] + maxCoins[i][right] ); } } } return maxCoins[0][n - 1]; } };
Runtime: 9 ms
题目链接:
312. Burst Balloons
题目大意:
给定 n 个气球, 序号为 1 到 n-1, 每个气球又对应一个分值, 分值用长度为 n 的数组 nums 表示 ; 现要求逐个打爆所有气球, 而每打爆一个序号为 i 的气球, 就可以得到 nums[left] * num[i] * nums[right] 的分值(即
coins), 其中 nums[left], nums[right] 分别表示与该气球相邻的两边的气球所对应的分值, 且该气球被打爆了之后, 就将其从序列中(气球序列 和 他们对应的分值的序列 都是)移除, 故 left, right 将会变成相邻项 ;
假设 nums[-1] = nums
= 1 ;
假设 0 <= n <= 500, 且 0 <= nums[i] <= 100 ;
例如: 给定: nums 为 [3, 1, 5, 8], 则输出应为:
167 ; ( 3*1*5 + 3*5*8 + 3*8 + 8 = 167 )
解题过程:
(1) 我一开始很单纯地觉得 每次取(除了两边端点处的气球外)分值最小的气球来打爆(若有同分/相邻/... 的情况另加判断) 的方式就可以了, 后来做了好久才发现不妥, 毕竟这样的朴素做法很容易就会浪费了极大值的价值 ;
(2) 后来(不加证明, 就随便想)想过几种方案, 发觉均有缺陷, 这点上一般可以简单地取极端情况验证 ;
(3) 然后联想到可能需要穷举式解决, 加上输入数据量确实颇小, 于是考虑动态规划, ... 然后为了验证想法, 就直接去 leetcode 上的 discussion 版块上看了下, 想法得以验证, 还顺便看到了答案 ... ( 帖子地址 )
;
(4) 答案的思路理解起来不难..., 这种 取样 处理的模式, 可以考虑针对每次所取的点作分割, 同时要注意到这里只要将 取样点 假设为要最后一个打爆的气球的话 其两边的 子序列 间是不会互相影响的(原序列中两端的分值为 1 的气球显然是不能打爆的, 而子序列中的两端的气球与
取样点气球 的交集又只有在(假设)打爆 取样点气球 的时候), 所以子序列间打爆气球的顺序就不重要了, 同时, 显然必然会存在这么一个要最后才打爆的气球 ;
代码如下:
class Solution { public: int maxCoins(vector<int> & nums) { vector<int> numbers; numbers.push_back(1); for (auto i : nums) { if (i > 0) { numbers.push_back(i); } } numbers.push_back(1); const auto n = numbers.size(); vector< vector<int> > maxCoins; maxCoins.resize(n); for (auto & v : maxCoins) { v.resize(n); } for (size_t k = 2; k < n; k++) { for (size_t left = 0; left < n - k; left++) { auto right = left + k; for (auto i = left + 1; i < right; i++) { maxCoins[left][right] = max( maxCoins[left][right], numbers[left] * numbers[i] * numbers[right] + maxCoins[left][i] + maxCoins[i][right] ); } } } return maxCoins[0][n - 1]; } };
Runtime: 9 ms
相关文章推荐
- [算法分析与设计] leetcode 每周一题: Validate Binary Search Tree
- [算法分析与设计] leetcode 每周一题: 335. Self Crossing
- [算法分析与设计] leetcode 每周一题: 467. Unique Substrings in Wraparound String
- [算法分析与设计] leetcode 每周一题: 070. Climbing Stairs
- [算法分析与设计] leetcode 每周一题: 542. 01 Matrix
- [算法分析与设计] leetcode 每周一题: Minimum Time Difference
- [算法分析与设计] leetcode 每周一题: 078. Subsets
- [算法分析与设计] leetcode 每周一题: Set Matrix Zeroes
- [算法分析与设计] leetcode 每周一题: 053. Maximum Subarray
- [算法分析与设计] leetcode 每周一题: Find Right Interval
- [算法分析与设计] leetcode 每周一题: 62. Unique Paths
- [算法分析与设计] leetcode 每周一题: Kth Smallest Element in a BST
- [算法分析与设计] leetcode 每周一题: 328. Odd Even Linked List
- [算法分析与设计] leetcode 每周一题: 420. Strong Password Checker
- [算法分析与设计] leetcode 每周一题: Contains Duplicate III
- [算法分析与设计] leetcode 每周一题: Surrounded Regions
- [算法分析与设计] leetcode 每周一题: Word Ladder
- [算法分析与设计] leetcode 每周一题: 667. Beautiful Arrangement II
- [算法分析与设计] leetcode 每周一题: 215. Kth Largest Element in an Array
- [算法分析与设计] leetcode 每周一题: UTF-8 Validation