664. Strange Printer
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.
Approach #1: DP. [C++]
class Solution { public: int strangePrinter(string s) { int len = s.length(); dp = vector<vector<int>>(len+1, vector<int>(len+1, 0)); return turn(s, 0, len-1); } private: vector<vector<int>> dp; int turn(const string& s, int i, int j) { if (i > j) return 0; if (dp[i][j] != 0) return dp[i][j]; int ans = turn(s, i, j-1) + 1; for (int k = i; k < j; ++k) if (s[k] == s[j]) ans = min(ans, turn(s, i, k)+turn(s, k+1, j-1)); dp[i][j] = ans; return dp[i][j]; } };
Approach #2: DP. [Java]
class Solution { public int strangePrinter(String s) { int len = s.length(); t_ = new int[len][len]; return turn(s.toCharArray(), 0, len-1); } public int turn(char[] s, int i, int j) { if (i > j) return 0; if (t_[i][j] > 0) return t_[i][j]; int ans = turn(s, i, j-1) + 1; for (int k = i; k < j; ++k) { if (s[k] == s[j]) ans = Math.min(ans, turn(s, i, k) + turn(s, k+1, j-1)); } t_[i][j] = ans; return t_[i][j]; } private int[][] t_; }
Approach #3: DP. [Python]
class Solution(object): def strangePrinter(self, s): """ :type s: str :rtype: int """ l = len(s) self._t = [[0 for _ in xrange(l)] for _ in xrange(l)] return self.turn(s, 0, l-1) def turn(self, s, i, j): if i > j: return 0 if self._t[i][j] > 0: return self._t[i][j] ans = self.turn(s, i, j-1) + 1 for k in xrange(i, j): if s[k] == s[j]: ans = min(ans, self.turn(s, i, k) + self.turn(s, k+1, j-1)) self._t[i][j] = ans return self._t[i][j]
Reference:
http://zxi.mytechroad.com/blog/dynamic-programming/leetcode-664-strange-printer/
永远渴望,大智若愚(stay hungry, stay foolish)