classSolution{// 思路:關心【最后一個被爆的氣球】,就不用關心后效性了(畢竟之后已經沒有氣球了)publicintmaxCoins(int[] nums){// 1. init: 處理開頭、結尾邊界(數字為 1 的氣球)int n = nums.length;int[] temp =newint[n +2];temp[0]=1;temp[n +1]=1;for(int i =0; i < n; i++){temp[i +1]= nums[i];}// 2. dp[i][j]: 開區間 (i, j) 的最大收益int[][] dp =newint[n +2][n +2];// 1)從小到大,開區間大小從 3 開始for(int len =3; len <= n +2; len++){// 2)左邊界for(int i =0; i <= n +2- len; i++){int res =0;// 3)被害氣球k,取值范圍開區間(i, i + len)for(int k = i +1; k < i + len -1; k++){int left = dp[i][k];int right = dp[k][i + len -1];// 迭代維護當前 i 開頭,大小為 len 的區間,可取的最大值res =Math.max(res, left + temp[i]* temp[k]* temp[i + len -1]+ right);}// 更新(i, i + len - 1)最大利益值dp[i][i + len -1]= res;}}return dp[0][n +1];}}
無注釋版
classSolution{publicintmaxCoins(int[] nums){int n = nums.length;int[] temp =newint[n +2];temp[0]=1;temp[n +1]=1;for(int i =0; i < n; i++){temp[i +1]= nums[i];}int[][] dp =newint[n +2][n +2];for(int len =3; len <= n +2; len++){for(int i =0; i <= n +2- len; i++){int res =0;for(int k = i +1; k < i + len -1; k++){int left = dp[i][k];int right = dp[k][i + len -1];res =Math.max(res, left + temp[i]* temp[k]* temp[i + len -1]+ right);}dp[i][i + len -1]= res;}}return dp[0][n +1];}}
二刷
再放送!還是覺得思路很強,期待三刷的時候能一股腦寫出來!
classSolution{publicintmaxCoins(int[] nums){// 1、init: 數組頭尾都添加元素 1int[] arr =newint[nums.length +2];arr[0]=1; arr[nums.length +1]=1;for(int i =1; i <= nums.length; i++){arr[i]= nums[i -1];}// 2、dp過程,三重循環1)2)3)int[][] dp =newint[arr.length][arr.length];// dp[i][j]: 開區間 (i, j) 的最大值// 1)開區間長度 len:初始為 3,最大為 arr.lengthfor(int len =3; len <= arr.length; len++){// 2)左邊界 i:初始為 0,最大為長度為 len 的開區間的最大值for(int i =0; i < arr.length - len +1; i++){int res =0;// 3)被害氣球 j:從(i, i + len - 1)中選一個被害氣球 j for(int j = i +1; j < i + len -1; j++){// 最優子結構 left、rightint left = dp[i][j];int right = dp[j][i + len -1];// 狀態轉移方程:子結構 + 爆炸取值res =Math.max(res, left + arr[i]* arr[j]* arr[i + len -1]+ right);}// 每次獲取(i, i + len - 1)的dp值,即范圍(i, i + len - 1)的最大值dp[i][i + len -1]= res;}}return dp[0][arr.length -1];// 返回整個數組的最大值}}
趁熱手打
classSolution{publicintmaxCoins(int[] nums){int[] arr =newint[nums.length +2];arr[0]=1;arr[nums.length +1]=1;for(int i =1; i < arr.length -1; i++){arr[i]= nums[i -1];}int[][] dp =newint[arr.length][arr.length];for(int len =3; len <= arr.length; len++){for(int i =0; i < arr.length - len +1; i++){int res =0;for(int j = i +1; j < i + len -1; j++){int left = dp[i][j];int right = dp[j][i + len -1];res =Math.max(res, left + arr[i]* arr[j]* arr[i + len -1]+ right);}dp[i][i + len -1]= res;}}return dp[0][arr.length -1];}}