546. 移除盒子

给出一些不同颜色的盒子,盒子的颜色由数字表示,即不同的数字表示不同的颜色。
你将经过若干轮操作去去掉盒子,直到所有的盒子都去掉为止。每一轮你可以移除具有相同颜色的连续 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. 1 <= boxes.length <= 100
  2. 1 <= boxes[i] <= 100

解答

参考官方题解,使用动态规划,假设索引r之后有k个与boxes[r]相同的颜色,则dp[l][r][k]记录从索引l到索引r消除颜色,加上右侧k个相同颜色带来的收益。
具体思路参考官方题解

class Solution {
public:
    int dp[100][100][100];
    int removeBoxes(vector<int>& boxes) {
        memset(dp, 0, sizeof(dp));
        return helper(boxes, 0, boxes.size()-1, 0);
    }
    int helper(vector<int>& boxes, int left, int right, int k){
        if(left>right)  return 0;
        if(dp[left][right][k]!=0)   return dp[left][right][k];
		//连着的颜色肯定一起消除带来的收益高
        while(left<right && boxes[right-1]==boxes[right]){
            right--;
            k++;
        }
		// l到r之间不先消除其他颜色以创造更长的连续块
        dp[left][right][k] = helper(boxes, left, right-1, 0) + (k+1)*(k+1);
        for(int i=left;i<right;i++){
            if(boxes[i]==boxes[right]){
            	// l到r之间还有和r相同的颜色块,将两相同颜色块之间的先消除,创造更长颜色块
                dp[left][right][k] = max(dp[left][right][k], helper(boxes, left, i, k+1) + helper(boxes, i+1, right-1, 0));
            }
        }
        return dp[left][right][k];
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值