JAVA程序设计:移除盒子(LeetCode:546)

本文介绍了一种使用记忆化搜索策略解决特定盒子移除问题的方法,旨在通过优化算法,实现对具有相同颜色的连续盒子进行移除并获取最大积分的过程。文章详细解析了算法的实现过程,包括状态定义、递归调用和状态更新,以及如何避免重复计算,提高算法效率。
摘要由CSDN通过智能技术生成

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

示例 1:
输入:

[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 分)
 

提示:盒子的总数 n 不会超过 100。

思路:我一开始竟然脑抽的去考虑如何用区间dp搞这道题,然后陷入卡题死循环中,后来无奈看了下题解,竟然忘了记忆化搜索这个操作了。。看来是最近写太少关于记忆化搜索的题目了。

没错,这道题整体思路是记忆化搜索,不过并不是简单的记忆区间的左右端点就行,我们需要多开一维来告诉我们当前子序列有多少个元素被合并在一起,具体的分析可以看官方题解,说的很详细。

class Solution {
    public int removeBoxes(int[] boxes) {
        
    	int[][][] dp=new int[100][100][100];
    	return calculatePoints(boxes,dp,0,boxes.length-1,0);
    }
    
    private int calculatePoints(int[] boxes,int[][][] dp,int l,int r,int k) {
    	
    	if(l>r) return 0;
    	if(dp[l][r][k]!=0) return dp[l][r][k];
    	
    	while(r>l && boxes[r]==boxes[r-1]) {r--;k++;}
    	dp[l][r][k]=calculatePoints(boxes,dp,l,r-1,0)+(k+1)*(k+1);
    	for(int i=l;i<r;i++) {
    		if(boxes[i]==boxes[r])
    			dp[l][r][k]=Math.max(dp[l][r][k], calculatePoints(boxes,dp,l,i,k+1)+calculatePoints(boxes,dp,i+1,r-1,0));
    	}
    	
    	return dp[l][r][k];
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值