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

涉及子串的动态规划一般从子串两端进行递推,即(i,j)子串。
分析如下:
dp[i][j][k]表示从i到j子串并且右端存在与j相同的k个字符其获得的最大点数。
有1,3,2,2,2,3,3
    i                          j                                   dp[i][j][1]       
此时有两种可选操作:
1、将j以及其后面的连续相同的串消除获得点数:dp[i][j-1][0]+(k+1)*(k+1)
      1,3,2,2,2,4,3,1  ——>  dp[i][j][0]+2*2
2、在子串内部寻找与右端相同的字符,将子串划分成两部分,先消除内部,再消除右端:dp[i][p][k+1]+dp[p+1][j-1][0]
      1,3,3,1  ——>  dp[i][p][k+1]
      2,2,2,4  ——>  dp[p+1][j-1][0]
dp[i][j][k]最大值为上面两种情况的最大值,代码如下:

public int removeBoxes(int[] boxes) {
        //涉及子串动态规划利用(i,j)进行递推
        int n=boxes.length;
        int dp[][][]=new int[n][n][n];
        return dfs(boxes,dp,0,n-1,0);
    }
    public int dfs(int[] boxes,int[][][]dp,int l,int r,int k){
        if(l>r)
            return 0;
        if(dp[l][r][k]>0)
            return dp[l][r][k];
        while(l1]){
            r--;
            k++;
        }
        dp[l][r][k]=dfs(boxes,dp,l,r-1,0)+(k+1)*(k+1);
        for(int i=l;iif(boxes[i]==boxes[r]){
               dp[l][r][k]=Math.max(dp[l][r][k],dfs(boxes,dp,l,i,k+1)+dfs(boxes,dp,i+1,r-1,0)); 
            }
        }
        return dp[l][r][k];
    }

http://blog.csdn.net/yy254117440/article/details/67638980

你可能感兴趣的:(Leetcode546. Remove Boxes)