546. Remove Boxes 移除盒子
给出一些不同颜色的盒子,盒子的颜色由数字表示,即不同的数字表示不同的颜色。
你将经过若干轮操作去去掉盒子,直到所有的盒子都去掉为止。每一轮你可以移除具有相同颜色的连续 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
数组里。我们可以操作的范围是l
到r
的子序列。由于我们对每个子序列默认都是点击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 移除盒子相关推荐
- leetcode 546. Remove Boxes
Solution 讲解: leetcode 546. Remove Boxes 很巧妙的分析思路:T(i, j, k) 来表示 k个相同前缀,i-j 之间的最大值 自己写的 自底向上的 Bottom ...
- LeetCode第 546 题:移除盒子(C++) (弃)
546. 移除盒子 - 力扣(LeetCode) 典型的动态规划最大值问题,单次移除的盒子个数(k)越多,得到的积分 k*k 就会越大,所以每次操作肯定会把连续的相同颜色的盒子都去掉. 注意: 这题还 ...
- [Leetcode][第546题][JAVA][移除盒子][递归][动态规划]
[问题描述][困难] [解答思路] 1. 递归 动态规划 class Solution {public int removeBoxes(int[] boxes) {int[][][] dp = new ...
- 「力扣」第 546 题:移除盒子(很难的动态规划问题)
参考的题解都已经在代码中注明了. 看这篇题解得到思路: https://leetcode-cn.com/problems/remove-boxes/solution/guan-fang-fang-fa ...
- LeetCode刷题实战546:移除盒子
算法的重要性,我就不多说了吧,想去大厂,就必须要经过基础知识和业务逻辑面试+算法面试.所以,为了提高大家的算法能力,这个公众号后续每天带大家做一道算法题,题目就从LeetCode上面选 ! 今天和大家 ...
- LeetCode 546. 移除盒子 | Python
546. 移除盒子 题目 给出一些不同颜色的盒子,盒子的颜色由数字表示,即不同的数字表示不同的颜色. 你将经过若干轮操作去去掉盒子,直到所有的盒子都去掉为止.每一轮你可以移除具有相同颜色的连续 k 个 ...
- leetcode 546. 移除盒子 —— 动态规划
将上面记忆化存储的递归算法,改为递推算法.即动态规划法. 546. 移除盒子 题目: 546. 移除盒子 给出一些不同颜色的盒子,盒子的颜色由数字表示,即不同的数字表示不同的颜色. 你将经过若干轮操作 ...
- Java实现 LeetCode 546 移除盒子(递归,vivo秋招)
546. 移除盒子 给出一些不同颜色的盒子,盒子的颜色由数字表示,即不同的数字表示不同的颜色. 你将经过若干轮操作去去掉盒子,直到所有的盒子都去掉为止.每一轮你可以移除具有相同颜色的连续 k 个盒子( ...
- LeetCode 546. 移除盒子 (很难的一道DP)
546. 移除盒子 不解释官方的了... 必须要知道的是,仅仅用[l,r][l,r][l,r]是不够记录状态的,子区间[l,r][l,r][l,r]不仅仅依赖于它的子区间,还依赖之前移动的顺序! 官方 ...
最新文章
- pgsql 安装详解
- python转换维度
- python 文件操作 os.listdir() 遍历文件
- python 压缩 解压
- spring—JdbcTemplate使用
- VSCode + git代码托管:入门到实战
- linux部署前后端分离项目命令笔记
- Git合并特定commits 到另一个分支
- 数据线CE测试标准 准备资料
- 【Unity3D】游戏配表Excel转Txt,并且打成ab包
- 【敏捷开发模式的介绍】
- 使用JavaScript开发IE浏览器本地插件实例
- 吉他效果器amplitube 4 mac 完整破解版永久激活方法
- 中维监控显示无法连接服务器失败,中维远程监控系统服务器端
- 化工自动化石油化工的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告
- HTML笔记(课堂笔记整合)
- 请教一下如何使用mdx文件
- 索尼电视投屏声音与画面不同步现象解决方案
- java动漫网站开题报告_动漫影响及其研究开题报告
- 苹果审核报 3.2,如何解决
热门文章
- 022-红黑树(三)
- 061 hive中的三种join与数据倾斜
- Android MP3录音实现
- 屏幕录像 Camstudio
- Js+DVML:很酷实用的右键弹出菜单
- java 二进制图片上传_Spring MVC上传图片,Java二进制图片写入数据库,生成略缩图...
- 给定圆的半径r,求圆的面积。
- string转换bigdecimal_使用MapStruct处理恼人的bean转换
- 堆中的路径 (25 分)
- rest post无法取到request_小白学Flask第五天 | 详解很重要的request对象