Leetcode 546. 移除盒子
本文最后更新于209 天前,其中的信息可能已经过时,如有错误请发送邮件到2446865563@qq.com

1.题目基本信息

1.1.题目描述

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

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

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

1.2.题目地址

https://leetcode.cn/problems/remove-boxes/description/

2.解题方法

2.1.解题思路

动态规划

2.2.解题步骤

第一步,状态定义。dp[i][j][k]表示boxes的[i,j]区间和右侧k个与boxes[j]相同的元素组成的子问题下的最大积分和

第二步,状态初始化。当i>j时,dp[i][j][*]=0,初始化时全部设置为0

第三步,状态转移。记previewPoints=dp[i][j-1][0],表示单独[i,j-1]区间进行移除的子问题下的最大积分和,其中当i==j时previewPoints=0;转移方程dp[i][j][k]=max(prevPoints+(k+1)*(k+1), max(dp[i][m][k+1]+dp[m+1][j-1][0] for m in range(i,j) if boxes[m]==boxes[j])),其中k的范围为0到n-j-1,这里枚举的是k的可能,实际的移除情况会包含在这些可能中。由于dp[i][j][k]依赖的状态的区间都比[i,j]区间的长度小,所以考虑使用区间动态规划

第四步,最终的dp[0][n-1][0]即为题解

3.解题代码

python代码

class Solution:
    def removeBoxes(self, boxes: List[int]) -> int:
        # 思路:动态规划
        n = len(boxes)
        # 第一步,状态定义。dp[i][j][k]表示boxes的[i,j]区间和右侧k个与boxes[j]相同的元素组成的子问题下的最大积分和
        dp = [[[0] * n for _ in range(n)] for _ in range(n)]
        # 第二步,状态初始化。当i>j时,dp[i][j][*]=0,初始化时全部设置为0
        # 第三步,状态转移。记previewPoints=dp[i][j-1][0],表示单独[i,j-1]区间进行移除的子问题下的最大积分和,其中当i==j时previewPoints=0;转移方程dp[i][j][k]=max(prevPoints+(k+1)*(k+1), max(dp[i][m][k+1]+dp[m+1][j-1][0] for m in range(i,j) if boxes[m]==boxes[j])),其中k的范围为0到n-j-1,这里枚举的是k的可能,实际的移除情况会包含在这些可能中。由于dp[i][j][k]依赖的状态的区间都比[i,j]区间的长度小,所以考虑使用区间动态规划
        for subLen in range(1, n + 1):
            for i in range(n - subLen + 1):
                j = i + subLen - 1
                maxCount = n - j - 1
                prevPoints = dp[i][j - 1][0] if i < j else 0
                for k in range(maxCount + 1):
                    maxPoints = prevPoints + (k + 1) * (k + 1)
                    for m in range(i, j):
                        if boxes[m] == boxes[j]:
                            maxPoints = max(maxPoints, dp[i][m][k + 1] + dp[m + 1][j - 1][0])
                    dp[i][j][k] = maxPoints
        # 第四步,最终的dp[0][n-1][0]即为题解
        return dp[0][n - 1][0]

c++代码

class Solution {
public:
    int removeBoxes(vector<int>& boxes) {
        int n = boxes.size();
        vector<vector<vector<int>>> dp(n, vector(n, vector(n, 0)));
        for (int subLen = 1; subLen <= n; subLen++) {
            for (int i = 0; i <= n - subLen; i++) {
                int j = i + subLen - 1;
                int maxCnt = n - j - 1;
                for (int k = 0; k <= maxCnt; k++) {
                    int prevPoints = i < j ? dp[i][j - 1][0] : 0;
                    int maxPoints = prevPoints + (k + 1) * (k + 1);
                    for (int m = i; m < j; m++) {
                        if (boxes[m] == boxes[j]) {
                            maxPoints = max(maxPoints, dp[i][m][k + 1] + dp[m + 1][j - 1][0]);
                        }
                    }
                    dp[i][j][k] = maxPoints;
                }
            }
        }
        return dp[0][n - 1][0];
    }
};

4.执行结果

觉得有帮助可以投喂下博主哦~感谢!

作者:geek007

转载请注明文章地址及作者哦~
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇