leetcode 664

问题

There is a strange printer with the following two special requirements:

  1. The printer can only print a sequence of the same character each time.
  2. 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:

1
2
3
Input: "aaabbb"
Output: 2
Explanation: Print "aaa" first and then print "bbb".

Example 2:

1
2
3
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.

分析

对于这个减1的处理方案有好多种,现在看起来依然不是太懂。

https://leetcode.com/problems/strange-printer/discuss/106810/Java-O(n3)-DP-Solution-with-Explanation-and-Simple-Optimization

不过这个视频中的方案看似理解起来比较容易一点。

https://www.youtube.com/watch?v=YQQUGsb7mww

代码1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// 152ms
class Solution {
public:
int strangePrinter(string s) {
int n = s.size();
if (n == 0) return 0;
vector<vector<int>> dp(n, vector<int>(n, n));
for (int i = 0; i < n; ++i) {
dp[i][i] = 1;
if (i < n-1) {
dp[i][i+1] = (s[i]==s[i+1])? 1: 2;
}
}
for (int len = 3; len <= n; ++len) {
for (int i = 0, j = i+len-1; j < n; ++i, ++j) {
for (int k = i; k < j; ++k) {
int t = dp[i][k] + dp[k+1][j];
if (s[k] == s[j])
dp[i][j] = min(dp[i][j], t-1);
else
dp[i][j] = min(dp[i][j], t);
}
}
}
return dp[0][n-1];
}
};

代码2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// 40ms
class Solution {
public:
vector<vector<int>> t_;
int strangePrinter(string s) {
int n = s.size();
t_ = vector<vector<int>>(n, vector<int>(n, 0));
return turn(s, 0, n-1);
}
int turn(const string &s, int i, int j) {
if (i > j) return 0;
if (i == j) return 1;
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 = min(ans, turn(s, i, k) + turn(s, k+1, j-1));
}
}
return t_[i][j] = ans;
}
};