列表

详情


546. 移除盒子

给出一些不同颜色的盒子 boxes ,盒子的颜色由不同的正数表示。

你将经过若干轮操作去去掉盒子,直到所有的盒子都去掉为止。每一轮你可以移除具有相同颜色的连续 k 个盒子(k >= 1),这样一轮之后你将得到 k * k 个积分。

返回 你能获得的最大积分和 。

 

示例 1:

输入:boxes = [1,3,2,2,2,3,4,3,1]
输出:23
解释:
[1, 3, 2, 2, 2, 3, 4, 3, 1] 
----> [1, 3, 3, 4, 3, 1] (3*3=9 分) 
----> [1, 3, 3, 3, 1] (1*1=1 分) 
----> [1, 1] (3*3=9 分) 
----> [] (2*2=4 分)

示例 2:

输入:boxes = [1,1,1]
输出:9

示例 3:

输入:boxes = [1]
输出:1

 

提示:

相似题目

奇怪的打印机

原站题解

去查看

上次编辑到这里,代码来自缓存 点击恢复默认模板
class Solution { public: int removeBoxes(vector<int>& boxes) { } };

python3 解法, 执行用时: 7788 ms, 内存消耗: 29.5 MB, 提交时间: 2023-06-02 09:41:16

# 依赖于 全部的长度1 及 尾部状态
class Solution:
    def removeBoxes(self, bs: List[int]) -> int:
        N = len(bs)
        dp = [[[0]* (N+1) for _ in range(N+1)] for _ in range(N+1)]
        for l in range(N):   # l++ 从小段 到 大段
            for i in range(N-l): # i++ 起点 从小到大
                j = i + l ;
                for t in range(N-j): # 尾部tail 同数 从小 到 大
                    dp[i][j][t]=max(dp[i][j][t],dp[i][j-1][0]+pow(t+1,2))
                    for k in range(i,j) : # 枚举 分割点 k
                        if bs[k] == bs[j]:
                            dp[i][j][t]=max(dp[i][j][t],\
                                dp[i][k][t+1]+dp[k+1][j-1][0])
        return dp[0][N - 1][0]

java 解法, 执行用时: 37 ms, 内存消耗: 54.4 MB, 提交时间: 2023-06-02 09:40:17

class Solution {
    int[][][] dp;

    public int removeBoxes(int[] boxes) {
        int length = boxes.length;
        dp = new int[length][length][length];
        return calculatePoints(boxes, 0, length - 1, 0);
    }

    public int calculatePoints(int[] boxes, int l, int r, int k) {
        if (l > r) {
            return 0;
        }
        if (dp[l][r][k] == 0) {
            int r1 = r, k1 = k;
            while (r1 > l && boxes[r1] == boxes[r1 - 1]) {
                r1--;
                k1++;
            }
            dp[l][r][k] = calculatePoints(boxes, l, r1 - 1, 0) + (k1 + 1) * (k1 + 1);
            for (int i = l; i < r1; i++) {
                if (boxes[i] == boxes[r1]) {
                    dp[l][r][k] = Math.max(dp[l][r][k], calculatePoints(boxes, l, i, k1 + 1) + calculatePoints(boxes, i + 1, r1 - 1, 0));
                }
            }
        }
        return dp[l][r][k];
    }
}

golang 解法, 执行用时: 36 ms, 内存消耗: 9.6 MB, 提交时间: 2023-06-02 09:40:04

func removeBoxes(boxes []int) int {
    dp := [100][100][100]int{}
    var calculatePoints func(boxes []int, l, r, k int) int
    calculatePoints = func(boxes []int, l, r, k int) int {
        if l > r {
            return 0
        }
        if dp[l][r][k] == 0 {
            r1, k1 := r, k
            for r1 > l && boxes[r1] == boxes[r1 - 1] {
                r1--
                k1++
            }
            dp[l][r][k] = calculatePoints(boxes, l, r1 - 1, 0) + (k1 + 1) * (k1 + 1)
            for i := l; i < r1; i++ {
                if boxes[i] == boxes[r1] {
                    dp[l][r][k] = max(dp[l][r][k], calculatePoints(boxes, l, i, k1 + 1) + calculatePoints(boxes, i + 1, r1 - 1, 0))
                }
            }
        }
        return dp[l][r][k]
    }
    return calculatePoints(boxes, 0, len(boxes) - 1, 0)
}

func max(x, y int) int {
    if x > y {
        return x
    }
    return y
}

golang 解法, 执行用时: 100 ms, 内存消耗: 9.6 MB, 提交时间: 2023-06-02 09:39:47

func removeBoxes(boxes []int) int {
    dp := [100][100][100]int{}
    var calculatePoints func(boxes []int, l, r, k int) int
    calculatePoints = func(boxes []int, l, r, k int) int {
        if l > r {
            return 0
        }
        if dp[l][r][k] == 0 {
            dp[l][r][k] = calculatePoints(boxes, l, r - 1, 0) + (k + 1) * (k + 1)
            for i := l; i < r; i++ {
                if boxes[i] == boxes[r] {
                    dp[l][r][k] = max(dp[l][r][k], calculatePoints(boxes, l, i, k + 1) + calculatePoints(boxes, i + 1, r - 1, 0))
                }
            }
        }
        return dp[l][r][k]
    }
    return calculatePoints(boxes, 0, len(boxes) - 1, 0)
}

func max(x, y int) int {
    if x > y {
        return x
    }
    return y
}

java 解法, 执行用时: 141 ms, 内存消耗: 54.4 MB, 提交时间: 2023-06-02 09:39:19

class Solution {
    int[][][] dp;  // dp[l][r][k] 表示移除区间[l, r] 加上该区间右边等于a[r]的k个元素组成的这个序列的最大分数

    public int removeBoxes(int[] boxes) {
        int length = boxes.length;
        dp = new int[length][length][length];
        return calculatePoints(boxes, 0, length - 1, 0);
    }

    public int calculatePoints(int[] boxes, int l, int r, int k) {
        if (l > r) {
            return 0;
        }
        if (dp[l][r][k] == 0) {
            dp[l][r][k] = calculatePoints(boxes, l, r - 1, 0) + (k + 1) * (k + 1);
            for (int i = l; i < r; i++) {
                if (boxes[i] == boxes[r]) {
                    dp[l][r][k] = Math.max(dp[l][r][k], calculatePoints(boxes, l, i, k + 1) + calculatePoints(boxes, i + 1, r - 1, 0));
                }
            }
        }
        return dp[l][r][k];
    }
}

上一题