这周完成的题目是关于动态规划和DFS的题目:Remove boxes。
Given several boxes with different colors represented by different positive numbers.
You may experience several rounds to remove boxes until there is no box left. Each time you can choose some continuous boxes with the same color (composed of k boxes, k >= 1), remove them and get k*k points.
Find the maximum points you can get.
Example 1:
Input:
[1, 3, 2, 2, 2, 3, 4, 3, 1]Output: 23
Explanation:
[1, 3, 2, 2, 2, 3, 4, 3, 1]
—-> [1, 3, 3, 4, 3, 1] (3*3=9 points)
—-> [1, 3, 3, 3, 1] (1*1=1 points)
—-> [1, 1] (3*3=9 points)
—-> [] (2*2=4 points)
Note: The number of boxes n would not exceed 100.
题目要求从左到右依次消除方块,颜色相同的k个方块可以一起消除,可以得到k*k分,求如何消除能够得到最高分。
分析:其实这道题是借助了题解才能想的出来,这也说明自己的积累还是不够==
假设对于串132223431,我们用一个三维数组rec[l][r][same_len],来记录从l到r的序列中,当第r个元素有same_len个相同的后缀元素时,消除这个序列能够得到的最高分。
假设dps函数能够找到从l到r的消除方块的最高分,对于dfs,我们假设其处理流程为:
整个过程的代码如下图所示:
class Solution {
private:
public:
/* l: 最左位置
* r: 最右位置
* same_len : 在r后面且与r相同的元素的长度
* rec: 记录从l到r的后缀长度为same_len时的消除值
* boxes: 所有盒子的颜色值
* 返回最终的最大的盒子值
*/
int dfs(int l, int r, int same_len, int rec[100][100][100], vector<int>& boxes){
if(l>r) return 0;
// 已经遍历过不需要再遍历
if(rec[l][r][same_len] > 0)
return rec[l][r][same_len];
while(r>l && boxes[r] == boxes[r-1]){
r--;
same_len++;
}
rec[l][r][same_len] = (same_len+1)*(same_len+1) + dfs(l,r-1,0,rec,boxes);
for(int i = l; i < r;i++)
if(boxes[i] == boxes[r])
// 如果发现这个值跟最右的值相等,存在两种可能
// 先消除最右的元素及其后缀元素的长度
// 消除当前值和最右值中间的元素再消除相同的元素值和当前元素值前面的元素
rec[l][r][same_len] = max(rec[l][r][same_len], dfs(l,i,same_len+1,rec,boxes)+dfs(i+1,r-1,0,rec,boxes));
return rec[l][r][same_len];
}
int removeBoxes(vector<int>& boxes) {
int rec[100][100][100] = {0};
return dfs(0,boxes.size()-1,0,rec,boxes);
}
};