题目简介:
给出一些不同颜色的盒子,盒子的颜色由数字表示,即不同的数字表示不同的颜色。
你将经过若干轮操作去去掉盒子,直到所有的盒子都去掉为止。每一轮你可以移除具有相同颜色的连续 k 个盒子(k >= 1),这样一轮之后你将得到 k*k
个积分。
当你将所有盒子都去掉之后,求你能获得的最大积分和。
示例:
1 | 输入:boxes = [1,3,2,2,2,3,4,3,1] |
提示:
1 <= boxes.length <= 100
1 <= boxes[i] <= 100
思路:
三维的动态规划,dp[left][right][num]
代表移除[left, right]
区间 和 [right + 1, maxsize]
区间内num
个与boxes[right]
相等的元素,所能达到的最大积分。
那么我们在移除元素时也有两种策略,就和玩祖玛游戏一样,有序列112231111
:
- 先把后面的四个1移除,那么就是
1123
+ 4 * 4 - 把中间碍事的先给去除,那么就是
22
+3
+ 6 * 6(6个1)
所以对于dp[left][right][num]
,我们有两种策略:
- 先将
right
后的num
个元素去除,那么就是dp[left][right - 1][0] + (num + 1) * (num + 1)
。(把boxes[right]
也去除了) - 在
[left, right]
区间内先找到一个点boxes[i] == boxes[right]
,那么dp[left][right][num] = dp[left][i][num + 1] + dp[i + 1][right - 1][0]
。(循环找到不止一个点,取最大值)
最后dp[left][right][num]
取两者最大值即可。
tips:
- 若
dp[left][right][num]
在之前已经计算出来,则直接返回结果即可。 - 否则利用深度优先搜索将其值计算出来。
代码如下:
1 | class Solution { |