您的位置:首页 > 编程语言 > C语言/C++

LeetCode 312. Burst Balloons--动态规划

2017-09-23 17:05 197 查看
题目链接

312. Burst Balloons

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
= 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) You
may imagine 
nums[-1] = nums
= 1
.
They are not real therefore you can not burst them.”  这句话)

1.子问题的解是父问题解的一部分,满足这个条件,符合动态规划的要求

2.注意到“求数组得到的最大值在最前和最后分别加一个1,1不能爆”,用dp[i][j]代表子序列(i,j)产生的最大值,不包括 i 和 j ,value[]表示每一位置的数值,value的大小是nums大小(size)加2,首位分别都是1,我们最后想得到的结果就可以用dp[0][size+1]表示

3.dp[i,j] = max(dp[i,last]+dp[last,j]+value[last]*value[i]*value[j]),i < last < j ,last的含义是在i和j之间最后爆的气球,last可以将一个序列分隔为2部分,序列的最大值就是2个子序列的最大值加上last爆时产生的值

代码(c++):

class Solution {
public:
int maxCoins(vector<int>& nums) {
int size = nums.size();
int dp[502][502] = {0};
int value[502];
value[0] = 1;
for (int i = 1; i <= size; i++) value[i] = nums[i-1];
value[size+1] = 1;
for (int i = 0; i < size-1; i++) dp[i][i+1] = 0;
for (int len = 2; len < size+2; len++) {
for (int i = 0; i < size; i++) {
int j = i+len;
for (int last = i+1; last <= j-1; last++) {
dp[i][j] = max(dp[i][j], dp[i][last] + dp[last][j] + value[last]*value[i]*value[j]);
}
}
}
return dp[0][size+1];
}
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息