题目链接:
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];
}
};
总之按照算法 勉强写下来了 但是 还是不太懂。。。。。 菜啊