546. 移除盒子

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];
    }
}
原文地址:https://www.cnblogs.com/yonezu/p/13509036.html