與矩陣連乘問題很相似:
Given
n
balloons, indexed from0
ton-1
. Each balloon is painted with a number on it represented by arraynums
. You are asked to burst all the balloons. If the you burst ballooni
you will getnums[left] * nums[i] * nums[right]
coins. Hereleft
andright
are adjacent indices ofi
. After the burst, theleft
andright
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]
≤ 100Example:
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
最後一個扎破的氣球要乘以原區間外相鄰左右兩邊的值,沒有時則乘以1,將nums轉化爲 a[1000],a[0] = a[n + 1] = 1,即可解決乘以1的問題,這題與矩陣連乘問題很相似,解決辦法也很相似。設 k 是最後一個扎破的氣球,dp[i][k - 1] 以及dp[k + 1][j]都是已經完全得到的具體數值,爲[],那麼僅需加上 a[i - 1] * a[k] * a[j - 1],i , j 分別爲所求區間的端點,L從1開始,經過判斷,對長度爲 1 的dp也可以按正確求得,注意 k = i; k <= j; 是正確的,雖然可能出現 k - 1 > i 的情況,但是由於已經初始化dp數組爲0,則不會產生影響。
class Solution {
public:
int a[1000];
int dp[501][501] = {0};
int maxCoins(vector<int>& nums) {
int n = nums.size();
for(int i = 0; i < n; i++)
a[i + 1] = nums[i];
a[0] = 1;
a[n + 1] = 1;
for(int L = 1; L <= n; L++)
{
for(int i = 1; i <= n - L + 1; i++)
{
int j = i + L - 1;
for(int k = i; k <= j; k++)
{
dp[i][j] = max(dp[i][j], dp[i][k - 1] + a[i - 1] * a[k] * a[j + 1] + dp[k + 1][j]);
}
}
}
return dp[1][n];
}
};