312. Burst Balloons

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

像这样

原文地址:https://www.cnblogs.com/wentiliangkaihua/p/11810011.html