给出一些不同颜色的盒子,盒子的颜色由数字表示,即不同的数字表示不同的颜色。
你将经过若干轮操作去去掉盒子,直到所有的盒子都去掉为止。每一轮你可以移除具有相同颜色的连续 k 个盒子(k >= 1),这样一轮之后你将得到 k*k 个积分。
当你将所有盒子都去掉之后,求你能获得的最大积分和。

示例:

输入: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 分)

提示:

  • 1 <= boxes.length <= 100
  • 1 <= boxes[i] <= 100

动态规划

首先,假设我们拿到的 boxes 长这样:

假设我们经过一系列操作后消掉了其中一些盒子:

对于这样一个子序列,我们就可以记录到dp数组里。我们可以操作的范围是lr的子序列。由于我们对每个子序列默认都是点击boxes[r]来消除,因此要知道r的后面还连着几个与boxes[r]相同颜色的盒子,记为k。如下图,l = 0, r = 6, k = 2, 将其能获得的最高得分记在dp[0][6][2]

现在我们调用 calculatePoints(i, r, k) 来计算它的最高得分 dp[i][r][k]

calculatePoints(i, r, k)

在我们这个子序列中,dp[0][6][2]dp[0][5][3] 实际上是等价的。我们将r向左一直移动到不能再移动为止。

接着,我们计算出不同策略的得分,取最高分。

策略 1

我们可以直接点boxes[r],把最后4个盒子一次性消除,获得16分!

剩下的盒子成为这样一个子序列 dp[0][4][0]

策略1得分:4*4 + dp[0][4][0]

策略 2

我们还可以把夹在中间的杂鱼盒子都消掉,让后面连起来的盒子数更多:

为了找到可以跟 boxes[r] 连起来的盒子,令 i = l

i++

直到 boxes[i] == boxes[r],就说明我们搜索到了

在这个例子中,消掉杂鱼盒子能获得的分数是 dp[3][4][0]

剩下的盒子的得分是 dp[0][2][4]

综上,策略2得分:dp[0][2][4] + dp[3][4][0]

总结

为了取得一个子序列的最高得分,我们分不同策略,每种策略的得分可以看作是1~2个子子序列的最高分之和。

Code

 def removeBoxes(self, boxes: List[int]) -> int:def dp(l, r, n):nonlocal memo, boxesif memo.get((l, r, n)):return memo[(l, r, n)]if l == r - 1:return (n + 1) * (n + 1)if boxes[l] == boxes[l + 1]:return dp(l + 1, r, n + 1)res = (n + 1) * (n + 1) + dp(l + 1, r, 0)for l2 in range(l + 2, r):if boxes[l2] == boxes[l]:res = max(res, dp(l + 1, l2, 0) + dp(l2, r, n + 1))memo[(l, r, n)] = resreturn resmemo = {}return dp(0, len(boxes), 0)

复杂度分析

  • 时间复杂度:O(n4)O(n^4)O(n4)。最坏情况下每个 f(l,r,k)f(l, r, k)f(l,r,k) 被计算一次,每次状态转移需要 O(n)O(n)O(n) 的时间复杂度。
  • 空间复杂度:O(n3)O(n^3)O(n3)。dp\rm dpdp 数组的空间代价是 O(n3)O(n^3)O(n3),递归使用栈空间的代价为 O(n)O(n)O(n)。

546. Remove Boxes 移除盒子相关推荐

  1. leetcode 546. Remove Boxes

    Solution 讲解: leetcode 546. Remove Boxes 很巧妙的分析思路:T(i, j, k) 来表示 k个相同前缀,i-j 之间的最大值 自己写的 自底向上的  Bottom ...

  2. LeetCode第 546 题:移除盒子(C++) (弃)

    546. 移除盒子 - 力扣(LeetCode) 典型的动态规划最大值问题,单次移除的盒子个数(k)越多,得到的积分 k*k 就会越大,所以每次操作肯定会把连续的相同颜色的盒子都去掉. 注意: 这题还 ...

  3. [Leetcode][第546题][JAVA][移除盒子][递归][动态规划]

    [问题描述][困难] [解答思路] 1. 递归 动态规划 class Solution {public int removeBoxes(int[] boxes) {int[][][] dp = new ...

  4. 「力扣」第 546 题:移除盒子(很难的动态规划问题)

    参考的题解都已经在代码中注明了. 看这篇题解得到思路: https://leetcode-cn.com/problems/remove-boxes/solution/guan-fang-fang-fa ...

  5. ​LeetCode刷题实战546:移除盒子

    算法的重要性,我就不多说了吧,想去大厂,就必须要经过基础知识和业务逻辑面试+算法面试.所以,为了提高大家的算法能力,这个公众号后续每天带大家做一道算法题,题目就从LeetCode上面选 ! 今天和大家 ...

  6. LeetCode 546. 移除盒子 | Python

    546. 移除盒子 题目 给出一些不同颜色的盒子,盒子的颜色由数字表示,即不同的数字表示不同的颜色. 你将经过若干轮操作去去掉盒子,直到所有的盒子都去掉为止.每一轮你可以移除具有相同颜色的连续 k 个 ...

  7. leetcode 546. 移除盒子 —— 动态规划

    将上面记忆化存储的递归算法,改为递推算法.即动态规划法. 546. 移除盒子 题目: 546. 移除盒子 给出一些不同颜色的盒子,盒子的颜色由数字表示,即不同的数字表示不同的颜色. 你将经过若干轮操作 ...

  8. Java实现 LeetCode 546 移除盒子(递归,vivo秋招)

    546. 移除盒子 给出一些不同颜色的盒子,盒子的颜色由数字表示,即不同的数字表示不同的颜色. 你将经过若干轮操作去去掉盒子,直到所有的盒子都去掉为止.每一轮你可以移除具有相同颜色的连续 k 个盒子( ...

  9. LeetCode 546. 移除盒子 (很难的一道DP)

    546. 移除盒子 不解释官方的了... 必须要知道的是,仅仅用[l,r][l,r][l,r]是不够记录状态的,子区间[l,r][l,r][l,r]不仅仅依赖于它的子区间,还依赖之前移动的顺序! 官方 ...

最新文章

  1. pgsql 安装详解
  2. python转换维度
  3. python 文件操作 os.listdir() 遍历文件
  4. python 压缩 解压
  5. spring—JdbcTemplate使用
  6. VSCode + git代码托管:入门到实战
  7. linux部署前后端分离项目命令笔记
  8. Git合并特定commits 到另一个分支
  9. 数据线CE测试标准 准备资料
  10. 【Unity3D】游戏配表Excel转Txt,并且打成ab包
  11. 【敏捷开发模式的介绍】
  12. 使用JavaScript开发IE浏览器本地插件实例
  13. 吉他效果器amplitube 4 mac 完整破解版永久激活方法
  14. 中维监控显示无法连接服务器失败,中维远程监控系统服务器端
  15. 化工自动化石油化工的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告
  16. HTML笔记(课堂笔记整合)
  17. 请教一下如何使用mdx文件
  18. 索尼电视投屏声音与画面不同步现象解决方案
  19. java动漫网站开题报告_动漫影响及其研究开题报告
  20. 苹果审核报 3.2,如何解决

热门文章

  1. 022-红黑树(三)
  2. 061 hive中的三种join与数据倾斜
  3. Android MP3录音实现
  4. 屏幕录像 Camstudio
  5. Js+DVML:很酷实用的右键弹出菜单
  6. java 二进制图片上传_Spring MVC上传图片,Java二进制图片写入数据库,生成略缩图...
  7. 给定圆的半径r,求圆的面积。
  8. string转换bigdecimal_使用MapStruct处理恼人的bean转换
  9. 堆中的路径 (25 分)
  10. rest post无法取到request_小白学Flask第五天 | 详解很重要的request对象