There is a strange printer with the following two special requirements:
Given a string consists of lower English letters only, your job is to count the minimum number of turns the printer needed in order to print it.
Example 1:
Input: "aaabbb" Output: 2 Explanation: Print "aaa" first and then print "bbb".
Example 2:
Input: "aba" Output: 2 Explanation: Print "aaa" first and then print "b" from the second place of the string, which will cover the existing character 'a'.
Hint: Length of the given string will not exceed 100.
664. Strange Printer 比 546. Remove Boxes简单,后者是前者的升级版。所以先写 664. Strange Printer。
这种题,先在脑中模拟如何工作的,选择一种有规律可循的策略,可以想如何分解为子问题。
可以从最左边开始涂,第一次把字符串都涂满(贪心思想),因为如果左边如果不是第一个涂,也可交换次序。以左边涂满后与最后完成时右边第一个保留的相同颜色的点,把问题分成子问题,右边第一个保留的点看作一个起始点。
对于每个s[i]==s[k],dp[i][j]=Math.max(1+dp[i+1][j],dp[i+1][k-1]+dp[k][j]);
时间复杂度O(n^3),空间复杂度O(n^2).
class Solution {
public int strangePrinter(String s) {
int len=s.length();
if(len==0) return 0;
int[][] dp=new int[len][len];
for(int k=0;kj-1?0:dp[i+1][j-1])+dp[j][i+k]);
}
}
}
}
}
return dp[0][len-1];
}
}
=============================================================================
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.
这题和上一题划分子问题的方式还是一样的,但比上一题多了一个分数的限制,需要在增加一维表式左边含有当前boxes[l]的个数。感觉这题自底向上写dp比较麻烦,参考了讨论区大神的做法是自顶向下方式写的dp比较多。所以这里也可以看出:有时记忆化dfs与dp的本质是一样的。自底向上dp待写。
另外需要适当的剪枝,初始连续的箱子就不会分开移动。
时间复杂度O(n^4),空间复杂度O(n^3)。
class Solution {
int[][][] dp=new int[100][100][100];
public int removeBoxes(int[] boxes) {
return dfs(boxes,0,boxes.length-1,0);
}
int dfs(int[] boxes,int l,int r,int c){
if(dp[l][r][c]>0) return dp[l][r][c];
if((lr?0:dfs(boxes,l+1,r,0));
for(int i=l+1;i<=r;i++){
if(boxes[i]==boxes[l]){
int p=i;
int c1=c;
while(i<=r&&boxes[i]==boxes[l]){//剪枝
c1++;
i++;
}
dp[l][r][c]=Math.max(dp[l][r][c],(l+1>p-1?0:dfs(boxes,l+1,p-1,0))+dfs(boxes,i-1,r,c1));
}
}
return dp[l][r][c];
}
}
参考:https://leetcode.com/problems/remove-boxes/discuss/101310/Java-top-down-and-bottom-up-DP-solutions