(71)546. 移除盒子(leetcode).

题目链接:
https://leetcode-cn.com/problems/remove-boxes/
难度:困难
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 <= boxes.length <= 100
	1 <= boxes[i] <= 100

这道题有点难啊!不会 知道是动态规划 但是一点都不会写 官方题解也看不太懂 不过结合另一位题解中的图 勉强懂了。。。
用 dp(l, r, k) 表示移除区间 [l, r] 加上该区间右边等于 boxes[r]​ 的 k 个元素组成的这个序列的最大积分
对于一个序列 两种情况
1. dp[ i ][ j ][ k ]=dp[ l ][ r-1 ] [ 0 ]+(k+1)2
2. dp[ i ][ j ][ k ]= max ( dp[ l ][ i ][ k+1 ]+dp[ i+1 ][ r-1 ][ 0 ] ) l <= i < r ( 条件:boxes[ i ]==boxes[ r ] )

class Solution {
    
    
public:
    int dp[100][100][100];
    int removeBoxes(vector<int>& boxes) {
    
    
        memset(dp, 0, sizeof dp);
        return getPoint(boxes,0,boxes.size()-1,0);
    }
    int getPoint(vector<int>& boxes,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]=getPoint(boxes,l,r-1,0)+(k+1)*(k+1);
        for(int i=l;i<r;++i){
    
    
            if(boxes[i]==boxes[r]){
    
    
                dp[l][r][k]=max(dp[l][r][k],getPoint(boxes,l,i,k+1)+getPoint(boxes,i+1,r-1,0));
            }
        }
        return dp[l][r][k];
    }
};

总之按照算法 勉强写下来了 但是 还是不太懂。。。。。 菜啊

猜你喜欢

转载自blog.csdn.net/li_qw_er/article/details/108018852