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[n] = 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
给定n个气球,每个气球对应一个数组中的元素,你需要将所有气球扎破,每扎破一个气球i,你将得到nums[left] * nums[i] * nums[right]个硬币,left和right为扎破气球左右相邻的气球,当气球I被扎破后,气球left和right就相邻了。
当扎破最左边的气球时,nums[left] = 1,当扎破最右边的气球时,nums[right] = 1。
本题可以采用动态规划的思想,rangeValues[i][j]代表扎破[i, j]范围内的气球所得到的最多硬币数,在nums头尾分别插入元素1,rangeValues[0][N]即为本题所求。
start、end分别表示range内最左和最右的下标,考虑最后一个被扎破的气球final,扎破它能得到nums[start-1] * nums[final] * nums[end+1]个硬币,之前扎破气球得到硬币rangeValue[start][final-1] + rangeValue[final+1][end],如果相加后coins大于bestCoins,则将coins赋值给bestCoins,那么bestCoins即为扎破[start, end]范围内的气球所得到的最多硬币数。
class Solution {
public:
int maxCoins(vector<int>& nums) {
int N = nums.size();
nums.insert(nums.begin(), 1);
nums.insert(nums.end(), 1);
// rangeValues[i][j] is the maximum # of coins that can be obtained
// by popping balloons only in the range [i,j]
vector<vector<int>> rangeValues(nums.size(), vector<int>(nums.size(), 0));
// build up from shorter ranges to longer ranges
for (int len = 1; len <= N; ++len) {
for (int start = 1; start <= N - len + 1; ++start) {
int end = start + len - 1;
// calculate the max # of coins that can be obtained by
// popping balloons only in the range [start,end].
// consider all possible choices of final balloon to pop
int bestCoins = 0;
for (int final = start; final <= end; ++final) {
int coins = rangeValues[start][final-1] + rangeValues[final+1][end]; // coins from popping subranges
coins += nums[start-1] * nums[final] * nums[end+1]; // coins from final pop
if (coins > bestCoins) bestCoins = coins;
}
rangeValues[start][end] = bestCoins;
}
}
return rangeValues[1][N];
}
};