Leetcode 546. Remove Boxes

题目链接:

https://leetcode.com/problems/remove-boxes/description/

问题描述

若干个有序排列的box和它们的颜色,每次可以移除若干个连续的颜色相同的box,且得分为移除个数的平方,求最大的得分。
n不超过100.

输入

输入n个箱子的颜色。

输出

输出最大的得分。

样例输入

1, 3, 2, 2, 2, 3, 4, 3, 1

样例输出

23

题解

令dp[l][r][k]表示前面有k个和box[l]同颜色的要和box[l]一起消除,现在考虑l是不是最后一个消的,这样的话可以得到转移方程:dp[l][r][k]=max((k+1)^2+dp[l+1][r][0],dp[l+1][m-1][0]+dp[m][r][k+1])(l+1<=m<=r);
这道题在状态的表示上比较有技巧,主要是因为涉及到了子问题的self-contain的问题,具体的可以看推荐题解

代码

int dp[101][101][101];
class Solution {
public:
    int dfs(vector<int>& nums,int l,int r,int k){
        if(l>r) return 0;
        if(l==r) return (k+1)*(k+1);
        if(dp[l][r][k]>=0) return dp[l][r][k];
        int ll=l,rr=r,kk=k;
        for(;l+1<=r&&nums[l]==nums[l+1];l++,k++);
        dp[l][r][k]=dfs(nums,l+1,r,0)+(k+1)*(k+1);
        for(int i=l+1;i<=r;i++){
            if(nums[i]==nums[l]){
                dp[l][r][k]=max(dp[l][r][k],dfs(nums,l+1,i-1,0)+dfs(nums,i,r,k+1));
            }
        }
        return dp[ll][rr][kk]=dp[l][r][k];
    }
    int removeBoxes(vector<int>& nums) {
        int n=nums.size();
        for(int i=0;i<n;i++) for(int j=i;j<n;j++) for(int k=0;k<n;k++) dp[i][j][k]=-1;
        return dfs(nums,0,n-1,0);
    }
};
原文地址:https://www.cnblogs.com/fenice/p/7721788.html