312. Burst Balloons
Hard
124534FavoriteShare
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
这道题我一开始想成是假设第k个先爆炸,但是这样列不出来转移方程,因为第k个左边和右边是耦合的。后来看了别人的做法,将第k个假设成最后一个爆炸的,这样就将左边和右边解耦合了,可以列转移方程。
dp[left][left+dist] = max(dp[left][left+dist],dp[left][k-1]+num[left-1]*num[k]*num[left+dist+1]+dp[k+1][left+dist])
为了处理nums[-1]和nums[n],我将nums向量复制到一个size+2的向量(num)中,0-size-1对应1-size,num[0]=num[size+1]=1;
因为在[left,left+dist]区间中,k从left开始,所以我使dp[i][i-1] = 0,(1<=i<=size+1);
class Solution {
public:
int maxCoins(vector<int>& nums)
{
int sizen = nums.size();
vector<int> num(sizen+2);
num[0]=1;
num[sizen+1]=1;
for(int i=1;i<sizen+1;i++)
{
num[i] = nums[i-1];
}
vector<vector<int> > dp(sizen+2,vector<int>(sizen+2,INT_MIN));
for(int i=1;i<=sizen+1;i++)
{
dp[i][i] = num[i];
dp[i][i-1] = 0;
}
for(int dist=0;dist<sizen;dist++)
for(int left = 1;left+dist<=sizen;left++)
for(int k=left;k<=left+dist;k++)
{
dp[left][left+dist] = max(dp[left][left+dist],dp[left][k-1]+num[left-1]*num[k]*num[left+dist+1]+dp[k+1][left+dist]);
}
return dp[1][sizen];
}
};