您的位置:首页 > 其它

312.Burst Balloons

2015-12-13 16:12 99 查看
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
1671


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

Credits:
Special thanks to @peisi for adding this problem and creating all test cases.

像这种求极值问题,我们一般都要考虑用动态规划Dynamic Programming来做,我们维护一个二维动态数组dp,其中dp[i][j]表示打爆区间[i,j]中的所有气球能得到的最多金币。题目中说明了边界情况,当气球周围没有气球的时候,旁边的数字按1算,这样我们可以在原数组两边各填充一个1,这样方便于计算。这道题的最难点就是找递归式,如下所示:
dp[i][j] = max(dp[i][j], nums[i - 1]*nums[k]*nums[j + 1] + dp[i][k - 1] + dp[k + 1][j]) i∈[1,n],j∈[1,n-i+1] k∈[j,j+i)

class Solution {
public:
int maxCoins(vector<int>& nums) {
int n=nums.size();
nums.insert(nums.begin(),1);
nums.insert(nums.end(),1);
vector<vector<int>>dp(n+2,vector<int>(n+2,0));
//dp[i][j]表示i到j求得的最大coin值
for(int len=1;len<=n;len++){//计算的气球下标范围长度
for(int start=1;start<=n-len+1;start++){//气球下标开始的位置范围
int end=start+len-1;//气球下标结束的位置
for(int x=start;x<=end;x++){
dp[start][end]=max(dp[start][end],dp[start][x-1]+nums[start-1]*nums[x]*nums[end+1]+dp[x+1][end]);
}
}
}
return dp[1]
;
}
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: