class Solution { public int removeBoxes(int[] boxes) { int n = boxes.length; int[][][] dp = new int[n][n][n]; // dp[i][j][k] 从i到j的盒子j右面右连续的等于第j个盒子颜色有k个 return dfs(boxes,0,n-1,0,dp); } public int dfs(int[] boxes, int i, int j, int k, int[][][] dp) { if(i > j) return 0; if(i == j) return (k+1)*(k+1); while(i < j && boxes[j] == boxes[j-1]) { j--; // 向前找到和j相同的盒子 优化! k++; } if(dp[i][j][k] > 0) return dp[i][j][k]; //记忆化 dp[i][j][k] = dfs(boxes,i,j-1,0,dp) + (k+1) * (k+1);// 先做一种选择,消去j以及j后面的盒子 for(int m = i; m < j; m++) { // 枚举前面的盒子 合并(其他选择) if(boxes[m] == boxes[j]) { dp[i][j][k] = Math.max(dp[i][j][k], dfs(boxes,i,m,k+1,dp) + dfs(boxes,m+1,j-1,0,dp)); } } return dp[i][j][k]; } }