There is a strange printer with the following two special requirements:
- The printer can only print a sequence of the same character each time.
- At each turn, the printer can print new characters starting from and ending at any places, and will cover the original existing characters.
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.
解题思路:
这道题是用动态规划+深度优先搜索来做。
状态转移方程如下:(dp[ i ][ j ] 表示打印[i j]区间字符序列所用最小次数)
- 可能每次只打印一个字符s[i] ,那么dp[i][j] = 1 + DFS(s , i + 1 , j) ;
- 对于[i j]之间的任一个字符s[k] , 如果s[k] == s[i] , 那么可以先将[i k]区间都打印成s[i]字符 ,再打印[i + 1 , k - 1 】 和 [k + 1 , j ]区间 ,所以dp[i][k] = dp[i][k - 1] , 那么dp[i][j] = min(dp[i][j] + DFS(s , i , k - 1) + DFS(s , k + 1 , j) ;
class Solution {
public:
int strangePrinter(string s)
{
dp = vector<vector<int>>(s.size() , vector<int>(s.size() , 0)) ;
return DFS(s , 0 , s.size() - 1 ) ;
}
int DFS(string& s , int i , int j)
{
if( i > j ) return 0 ;
if(dp[i][j] > 0) return dp[i][j] ;
dp[i][j] = 1 + DFS(s , i + 1 , j) ;
for(int k = i + 1 ; k <= j ; k++)
{
if(s[k] == s[i]) dp[i][j] = min(dp[i][j] , DFS(s , i , k - 1) + DFS(s , k + 1 , j)) ;
}
return dp[i][j] ;
}
private :
vector<vector<int>> dp ;
};