首页 > 其他分享 >leetcode 546. 移除盒子

leetcode 546. 移除盒子

时间:2023-07-19 14:46:36浏览次数:48  
标签:盒子 calculate int 积分 boxes 546 移除 leetcode dp

1. 题目

读题

 链接:https://www.nowcoder.com/questionTerminal/a5390d76441647fbb182f34bee6a1ca7
来源:牛客网
一维消消乐

小v在vivo手机的应用商店中下载了一款名为“一维消消乐”的游戏,介绍如下:
1、给出一些不同颜色的豆子,豆子的颜色用数字(0-9)表示,即不同的数字表示不同的颜色; 2、通过不断地按行消除相同颜色且连续的豆子来积分,直到所有的豆子都消掉为止; 3、假如每一轮可以消除相同颜色的连续 k 个豆子(k >= 1),这样一轮之后小v将得到 k*k 个积分; 4、由于仅可按行消除,不可跨行或按列消除,因此谓之“一维消消乐”。
请你帮助小v计算出最终能获得的最大积分。   这道题  和 leetcode 546. 移除盒子  是同一道原题

 

考查点

 

2. 解法

思路

  • 定义一个三维数组dp[i][j][k],表示区间[i,j]内,左边有k个与boxes[j]相同的盒子时的最大积分。
  • 动态转移方程是,

dp[i][j][k] = max(calculate(boxes, dp, i, j - 1, 0) + (k + 1) * (k + 1), calculate(boxes, dp, i, m, k + 1) + calculate(boxes, dp, m + 1, j - 1, 0)),其中m是区间[i,j-1]内与boxes[j]相同颜色的盒子的下标。

  • 这个方程的意思是,我们可以选择移除最右边的盒子,或者将区间内与最右边盒子相同颜色的盒子移动到右边,然后计算两个子问题的最大积分和。我们需要在这两种选择中取最大值作为当前状态的值。

 

 

代码逻辑

 

  • 首先,我们需要定义一个三维数组dp[i][j][k],表示区间[i,j]内,左边有k个与boxes[j]相同的盒子时的最大积分。
  • 然后,我们需要找到状态转移方程,即如何从已知的状态得到未知的状态。
  • 一种基本的情况是,我们只移除最右边的盒子,那么我们可以得到dp[i][j][k] = calculate(boxes, dp, i, j - 1, 0) + (k + 1) * (k + 1),其中calculate是一个递归函数,用来计算子问题的答案。
  • 另一种情况是,我们尝试将区间[i,j-1]内与boxes[j]相同颜色的盒子移动到右边,这样可以增加积分。为了找到这样的盒子,我们需要遍历区间[i,j-1],并且判断是否有boxes[m] == boxes[j]。如果有,那么我们可以将区间[i,j-1]分成两个子区间[i,m]和[m+1,j-1],并且计算它们的最大积分和。
  • 我们需要在这两种情况中选择最大的积分作为dp[i][j][k]的值,并且记录下来,避免重复计算。
  • 最后,我们返回dp[0][n-1][0]作为最终答案,其中n是盒子的数量。

具体实现

class Solution {
    public int removeBoxes(int[] boxes) {
        // dp[i][j][k]表示区间[i,j]内,左边有k个与boxes[j]相同的盒子时的最大积分
        int[][][] dp = new int[100][100][100];
        return calculate(boxes, dp, 0, boxes.length - 1, 0);
    }

    public int calculate(int[] boxes, int[][][] dp, int i, int j, int k) {
        if (i > j) return 0; // 空区间
        if (dp[i][j][k] != 0) return dp[i][j][k]; // 已经计算过
        // 优化:合并右边连续相同颜色的盒子
        while (i < j && boxes[j] == boxes[j - 1]) {
            j--;
            k++;
        }
        // 基本情况:只移除最右边的盒子
        dp[i][j][k] = calculate(boxes, dp, i, j - 1, 0) + (k + 1) * (k + 1);
        // 尝试将区间[i,j-1]内与boxes[j]相同颜色的盒子移动到右边
        for (int m = i; m < j; m++) {
            if (boxes[m] == boxes[j]) {
                // 计算两个子区间的最大积分和
                dp[i][j][k] = Math.max(dp[i][j][k], calculate(boxes, dp, i, m, k + 1) + calculate(boxes, dp, m + 1, j - 1, 0));
            }
        }
        return dp[i][j][k];
    }
}

 

3. 总结

 

标签:盒子,calculate,int,积分,boxes,546,移除,leetcode,dp
From: https://www.cnblogs.com/shoshana-kong/p/17565498.html

相关文章

  • [LeetCode] 2461. Maximum Sum of Distinct Subarrays With Length K
    Youaregivenanintegerarray nums andaninteger k.Findthemaximumsubarraysumofallthesubarraysof nums thatmeetthefollowingconditions:Thelengthofthesubarrayis k,andAlltheelementsofthesubarrayare distinct.Return themaxim......
  • [LeetCode] 2222. Number of Ways to Select Buildings
    Youaregivena 0-indexed binarystring s whichrepresentsthetypesofbuildingsalongastreetwhere:s[i]='0' denotesthatthe ith buildingisanofficeands[i]='1' denotesthatthe ith buildingisarestaurant.Asacityoff......
  • Leetcode日记
    日期题号题目解法难度2023-07-112741给定一个互不相同的正整数数组,找出特别排列(相邻元素互模任一为0)的总数目。取余dp+记忆,位运算,取余注意先加后取⭐⭐⭐1911求数组最大子序列交替和(偶数下标元素和减奇数下标元素和)dp⭐2023-07-121857有向图中求路径......
  • LeetCode 35.搜索插入位置
    题目:给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。请必须使用时间复杂度为 O(logn) 的算法。示例1:输入:nums=[1,3,5,6],target=5输出:2示例 2:输入:nums=[1,3,5,6],target=2输出:1......
  • LeetCode 852. Peak Index in a Mountain Array 二分
    Anarrayarramountainifthefollowingpropertieshold:arr.length>=3Thereexistssomeiwith0<i<arr.length-1suchthat:arr[0]<arr[1]<...<arr[i-1]<arr[i]arr[i]>arr[i+1]>...>arr[arr.length-......
  • 2023-07-18:给你一个正整数数组 nums,请你移除 最短 子数组(可以为 空), 使得剩余元素的 和
    2023-07-18:给你一个正整数数组nums,请你移除最短子数组(可以为空),使得剩余元素的和能被p整除。不允许将整个数组都移除。请你返回你需要移除的最短子数组的长度,如果无法满足题目要求,返回-1。子数组定义为原数组中连续的一组元素。输入:nums=[3,1,4,2],p=6。输出:1。答......
  • 2023-07-18:给你一个正整数数组 nums,请你移除 最短 子数组(可以为 空), 使得剩余元素的 和
    2023-07-18:给你一个正整数数组nums,请你移除最短子数组(可以为空),使得剩余元素的和能被p整除。不允许将整个数组都移除。请你返回你需要移除的最短子数组的长度,如果无法满足题目要求,返回-1。子数组定义为原数组中连续的一组元素。输入:nums=[3,1,4,2],p=6。输......
  • 8-102-(LeetCode- 207&210) 课程表
    1.题目 读题  考查点 2.解法思路这个问题可以用图论的方法来解决,具体思路如下:将课程和先修课程看作有向图的节点和边,如果要学习课程ai,则必须先学习课程bi,表示为bi->ai。判断图中是否存在环,如果存在环,则说明有些课程无法完成,返回false;如果不存在环,则说明所有课程都......
  • leetcode104二叉树搜索
    深度优先搜索,递归maxDepth(TreeNode*root){if(!root)return0;returnmax(maxDepth(root->left),maxDepth(root->right))+1;} 广度优先搜索,队列queue<TreeNode*>q;q.push(root);while(!q.empty()){intsize=q.size();while(size>0){Tree......
  • LeetCode 301. 删除无效的括号
    classSolution{public:vector<string>ans;vector<string>removeInvalidParentheses(strings){//lr分别记录要删除的左右括号数量intl=0,r=0;for(autoc:s)if(c=='(')l++;elseif(c=='......