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
/* 动态规划:
* dp[i][j] 为打爆[i,j]内气球获得的最大奖励, 则
* [i,j] 区间划分为: [i,k-1] k [k+1, j]
* dp[i][j] = max(dp[i][j], nums[i-1]*nums[k]*nums[j+1]+dp[i][k-1]+dp[k+1][j]) i<=k<=j
* 这是因为dp[i][k-1] 表示把[i,k-1] 区间内气球全部打爆, 和k左侧相邻的气球就是i-1
* */
class Solution {
public:
int maxCoins(vector<int>& nums) {
int n=nums.size();
vector<vector<int>> dp(n+2, vector<int>(n+2, 0)); // 注意两侧是填入的哨兵
nums.insert(nums.begin(), 1);
nums.push_back(1);
// nums[0]=nums[n+1]=1; nums[1:n] 之前才是原本的数组
// 外循环对区间长度(包含元素个数)遍历, i j 为区间两端 len= j-i+1, imin=0, jmax=n+1
for(int len=1;len<=n;len++){
for(int i=1;i<=n-len+1;i++){// j=len+i-1<=n i<=n-len+1
int j=len+i-1;
for(int k=i;k<=j;k++){
dp[i][j] = max(dp[i][j], nums[i-1]*nums[k]*nums[j+1]+dp[i][k-1]+dp[k+1][j]);
}
}
}
return dp[1][n];
}
};