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 class Solution { 2 public: 3 int maxCoins(vector<int>& nums) { 4 int len = nums.size(); 5 vector<int> num(len + 2, 1); 6 for (int i = 0; i < len; i++) 7 num[i + 1] = nums[i]; 8 vector<vector<int> > memo(len + 2, vector<int>(len + 2, -1)); 9 return maxCoins(num, memo, 0, len + 1); 10 } 11 private: 12 //表示(start, end)内的气球都点燃可以获得的最大钱数。 13 int maxCoins(vector<int> &nums, vector<vector<int> > &memo, int start, int end) { 14 if (memo[start][end] != -1) 15 return memo[start][end]; 16 if (end - start == 1) 17 memo[start][end] = 0; 18 else { 19 int income = 0; 20 //分治。(start, i) 和 (i, end) 分别获得的最大钱数 + 点燃i的钱数 21 for (int i = start + 1; i < end; i++) { 22 income = max(income, maxCoins(nums, memo, start, i) + maxCoins(nums, memo, i, end) + nums[start] * nums[i] * nums[end]); 23 } 24 memo[start][end] = income; 25 } 26 return memo[start][end]; 27 } 28 };
方法二:动态规划(bottom up), 先解决只有一个气球,两个气球,...,
1 class Solution { 2 public: 3 int maxCoins(vector<int>& nums) { 4 int len = nums.size(); 5 vector<int> num(len + 2, 1); 6 for (int i = 0; i < len; i++) { 7 num[i + 1] = nums[i]; 8 } 9 vector<vector<int> > dp(len + 2, vector<int>(len + 2, 0)); //dp[i][j]表示点燃所有下标(i, j)内的气球所能得到的最大钱数 10 int n = len + 2; 11 for (int k = 1; k <= n; k++) { //从长度为1的开始算起 12 for (int left = 0; left < n - 1 - k; left++) { 13 int right = left + k + 1; 14 for (int i = left + 1; i < right; i++) { 15 dp[left][right] = max(dp[left][right], num[left] * num[i] * num[right] + dp[left][i] + dp[i][right]); 16 } 17 } 18 } 19 return dp[0][n - 1]; 20 } 21 };