A very interesting question!
Think that we have N balloons to shot.
0 - 1 - 2 .... - n-1 in order to get the best score, we want to shot a special balloon, name it as k.
Then, we can get that.
0 - 1- 2 ... - k-1, K, k+1 - k+2 ... n-1
Thus, the bestCoins we can get by shotting K is: bestCoins(0, k-1) + coins(K) + bestCoins(k+1, n-1).
Be careful that bestCoins(0, k-1) and bestCoins(k+1, n-1) means that we know which balloons to shot and have been shot.
Coins(K) means : nums[k] * nums[i-1] * nums[j+1].
#include <vector> #include <iostream> using namespace std; /* 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 ballons wisely. 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] --> [] the maxCoins is 167. */ int maxCoins(vector<int>& nums) { /* suppose we use dp[i][j] to stand for maxCoins from (index i to index j) And, the best shoting index is k. Thus, dp[i][j] = dp[i][k-1] + dp[k+1][j] + nums[i-1]*nums[k-1]*nums[j+1]; 0 <= i < n; i <= j < n; i <= k <= j */ int N = nums.size(); nums.insert(nums.begin(), 1); nums.insert(nums.end(), 1); int n = nums.size(); vector< vector<int> > dp(n, vector<int>(n, 0)); // This len variable trick is also pretty important. for(int len = 1; len <= N; ++len) { for(int start = 1; start <= N - len + 1; ++start) { int end = start + len - 1; int bestCoins = 0; for(int k = start; k <= end; ++k) { int coins = dp[start][k - 1] + dp[k + 1][end]; coins += nums[start - 1] * nums[k] * nums[end + 1]; if(coins > bestCoins) bestCoins = coins; } dp[start][end] = bestCoins; } } return dp[1][N]; } int main(void) { vector<int> nums{3, 1, 5, 8}; cout << maxCoins(nums) << endl; }