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
Example:
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
https://www.youtube.com/watch?v=z3hu2Be92UA
花花大佬牛逼
一张图包含所有要点。
c[ i ] [ j ]如上所述
把题目想象成最后剩下了k,k前面的子串和后面的子串都已经爆完,这时候就是前子串 + 爆k + 后子串。
具体实现可以通过递归
class Solution { public int maxCoins(int[] nums) { int n = nums.length; int[] newnums = new int[n + 2]; newnums[0] = 1; newnums[n + 1] = 1; for(int i = 0; i < n; i++){ newnums[i + 1] = nums[i]; } int[][] C = new int[n + 2][n + 2]; return helper(newnums, C, 1, n); } int helper(int[] nums, int[][] C, int s, int e){ if(s > e) return 0; if(C[s][e] > 0){ return C[s][e]; } for(int i = s; i <= e; i++){ int v = nums[s - 1] * nums[i] * nums[e + 1] + helper(nums, C, s, i - 1) + helper(nums, C, i + 1, e); C[s][e] = Math.max(C[s][e], v); } return C[s][e]; } }
其中if(C[ s ] [ e ] > 0)是为了避免重复,否则会TLE,在最内循环中才需要和前面的结果比较大小,因为cse循环结束后部根据helper的调用而变化。
for循环是因为i的位置未知,需要不停计算来最后确认。
s - 1, (s, ..., i - 1), i, (i + 1, ..., e), e + 1
像这样