546. 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.

给定若干个不同颜色的盒子,用不同数字表示。每次选择连续的k个相同颜色的箱子进行消除,消除一次得到k*k的分数,直到把所有箱子消除,求最多能得到的分数。


思路:这道题和之前做过的Burst Balloons很相似http://blog.csdn.net/lizhb5/article/details/68490522,都是将一个区间的长度由n缩小为1,而且缩小的规则都与左右两边的数字有关系。所以用枚举的方法显然是不行的,由以前的题启发可知,显然这道题要用动态规划来做。仿照上一题的做法,建立一个二维数组dp[left][right]记录区间[left,right]之间的最大得分。但是这道题消除的规则有些不一样,是对连续k个相同颜色的箱子进行消除,所以状态转移的时候需要增加一维记录这个k,要建立一个三维数组dp[left][right][k]表示,区间[left,right]之间,并且right之后还有k个颜色与right相同的箱子能得到的最大分数。那么dp[left][right][k] = dp[left][right-1][0] + (len[right]+k)*(len[right]+k)。在区间left和right之间任意一个点如果能进行消除,那么就要更新分数,假设 消除的点为i,那么dp[left][right][k] = max(dp[left][right][k], dp[left][i][len(r)+k]+dp[i+1][right][0])。直到区间的left比right大,就结束更新,得到最大的分数了。

class Solution {
public:
    int removeBoxes(vector<int>& boxes)
    {
        int n=boxes.size();
        int dp[100][100][100] = {0};//三维数组记录得分
        return dfs(boxes,dp,0,n-1,0);
    }
    int dfs(vector<int>& boxes, int dp[100][100][100],int left, int right, int length)
    {
        if(left > right)//假如左边的坐标大于右边,得0分
            return 0;
        if(dp[left][right][length] != 0)
            return dp[left][right][length];
        while(right > 1 && boxes[right] == boxes[right-1])//统计连续几个相同的盒子
        {
            length++;
            right--;
        }
        dp[left][right][length] = dfs(boxes,dp,left,right-1,0) + (length+1)*(length+1);//计算合并后的得分
        for(int i = left; i < right; ++i)
        {
            if(boxes[i] == boxes[right])
                dp[left][right][length] = max(dp[left][right][length], dfs(boxes,dp, left,i,length+1)//中间合并后更新分数
                +dfs(boxes,dp,i+1,right-1,0));
        }
        return dp[left][right][length];
    }
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值