There is a stone game.At the beginning of the game the player picksnpiles of stones in a line.
The goal is to merge the stones in one pile observing the following rules:
At each step of the game,the player can merge two adjacent piles to a new pile.
The score is the number of stones in the new pile.
You are to determine the minimum of the total score.
Example
For[4, 1, 1, 4], in the best solution, the total score is18:
1. Merge second and third piles => [4, 2, 4], score +2
2. Merge the first two piles => [6, 4],score +6
3. Merge the last two piles => [10], score +10
Other two examples:
[1, 1, 1, 1]return8[4, 4, 5, 9]return43
要分开算sum。
publicintstoneGame(int[] A) {if (A ==null||A.length==0) {return0; }int n =A.length;int[][] dp =newint[n][n];int[] sum =newint[n +1];// because we want to get min, so init to MAXfor (int i =0; i < n; i++) {for (int j = i; j < n; j++) { dp[i][j] =Integer.MAX_VALUE; } }// init diagonalfor (int i =0; i < n; i++) { dp[i][i] =0; sum[i +1] = sum[i] +A[i]; }// mem searchcalRange(A,0, n -1, dp, sum);return dp[0][n -1];}privateintcalRange(int[] A,int s,int e,int[][] dp,int[] sum) {// we calculate the range before, so just return it// note : don't try to use dp[][] > 0, because 0 is also a valid valueif (dp[s][e] !=Integer.MAX_VALUE) { return dp[s][e]; }// if we never calculate, we calculate hereint min =Integer.MAX_VALUE;int rangeSum = sum[e +1] - sum[s];for (int i = s; i < e; i++) {int cur =0;int r1 =calRange(A, s, i, dp, sum);int r2 =calRange(A, i +1, e, dp, sum); cur = r1 + r2 + rangeSum; min =Math.min(min, cur); } dp[s][e] = min;return dp[s][e];}