题意
给定一个字符串,现在问将字符串最多分割几刀使每一段都是回文串?
思路
我们首先考虑因为要判断一段是否为回文串,因此需要先预处理出所有区间是否为回文串。
状态表示:f[i,j],区间[i, j]是否为回文串。
转移方程:f[i,j]=(si==sj?f[i+1,j−1]:0)
当我们预处理完成后,需要进行切割次数的dp了。由之前wordBreak可以很容易想到:
状态表示:d[i],从s0i的最小分割次数。
转移方程:d[i]=min{d[j]+1|f[j+1,i]==1}
代码
const int maxn = 2005;
int d[maxn], f[maxn][maxn];
class Solution {
public:
int dfs(int i) {
if (d[i] != -1) return d[i];
if (f[0][i]) return d[i] = 1;
d[i] = 0x3e3e3e3e;
for (int j = 0; j < i; j++) {
if (f[j + 1][i]) {
d[i] = min(d[i], dfs(j) + 1);
}
}
return d[i];
}
int minCut(string s) {
int n = s.length();
if (!n || n == 1) return 0;
for (int i = n - 1; i >= 0; i--) {
for (int j = i; j < n; j++) {
if (i == j) f[i][j] = 1;
else {
if (s[i] == s[j]) {
if (j == i + 1) f[i][j] = 1;
else f[i][j] = f[i + 1][j - 1];
} else {
f[i][j] = 0;
}
}
}
}
memset(d, -1, sizeof(d));
return dfs(n - 1) - 1;
}
};