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.java
Find the maximum coins you can collect by bursting the balloons wisely.code
Note:遊戲
nums[-1] = nums[n] = 1
. They are not real therefore you can not burst them.n
≤ 500, 0 ≤ nums[i]
≤ 100Example:get
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
打氣球遊戲。每一個氣球有對應的分值,打爆一個氣球i,能獲得的積分爲氣球i、氣球i-一、氣球i+1積分的乘積。要求計算可以得到的最大積分。it
動態規劃問題。dp[left, right]表示打爆從left到right全部氣球能獲得的最大積分。每一次咱們在[left, right]這個區間中選擇一個i,表明該區間中最後一個被打爆的氣球,那麼能夠獲得遞推關係式:io
class Solution { public int maxCoins(int[] nums) { int[][] memo = new int[nums.length][nums.length]; for (int i = 0; i < nums.length; i++) { Arrays.fill(memo[i], -1); } return dfs(nums, 0, nums.length - 1, memo); } private int dfs(int[] nums, int left, int right, int[][] memo) { if (right < left) { return 0; } if (memo[left][right] != -1) { return memo[left][right]; } int max = 0; for (int i = left; i <= right; i++) { int x = dfs(nums, left, i - 1, memo) + dfs(nums, i + 1, right, memo) + nums[i] * (left == 0 ? 1 : nums[left - 1]) * (right == nums.length - 1 ? 1 : nums[right + 1]); max = Math.max(max, x); } memo[left][right] = max; return max; } }
class Solution { public int maxCoins(int[] nums) { if (nums.length == 0) { return 0; } int[][] dp = new int[nums.length][nums.length]; for (int right = 0; right < nums.length; right++) { for (int left = right; left >= 0; left--) { for (int i = left; i <= right; i++) { int leftMax = i == left ? 0 : dp[left][i - 1]; int rightMax = i == right ? 0 : dp[i + 1][right]; int last = nums[i] * (left == 0 ? 1 : nums[left - 1]) * (right == nums.length - 1 ? 1 : nums[right + 1]); dp[left][right] = Math.max(dp[left][right], leftMax + rightMax + last); } } } return dp[0][nums.length - 1]; } }