题目描述:
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
给定n个气球,每个气球代表一个数值,当戳破气球i就会获得nums[left]*nums[i]*nums[right]个硬币,求戳破所有的气球可能获得的最大的硬币数。自然是利用动态规划,但是递推关系并不好找,dp[i][j]表示戳破从气球i到气球j的所有气球得到的最大硬币数,那么对于i<=k<=j,有递推公式dp[i][j]=max(dp[i][j],nums[k]*nums[i-1]*nums[j+1]+dp[i][k-1]+dp[k+1][j]),由于是按照对角线的顺序遍历动态规划的矩阵,所以递推的循环写法稍有改变。
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));
for(int count=1;count<=n;count++)
{
int i=1;
for(int j=count;j<=n;j++)
{
for(int k=i;k<=j;k++)
dp[i][j]=max(dp[i][j],nums[k]*nums[i-1]*nums[j+1]+dp[i][k-1]+dp[k+1][j]);
i++;
}
}
return dp[1][n];
}
};