原题链接

g[i][j] 用于快速判断 SiSjS_i \sim S_j 是不是回文串。

f[i] 表示前 i 个字符的分割方案数中的最小值。由于终点 i 固定,可以将分割方案划分成分割后字符串 S 最后一段为 1 ~ i2 ~ i 一直到 i ~ i 这些类。所有方案取最小值就是 f[i] 的值。

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
class Solution {
public:
int minCut(string s) {
int n = s.size();
s = ' ' + s;
vector<vector<bool>> g(n + 1, vector<bool>(n + 1, false));
vector<int> f(n + 1, 1e8);
for(int j=1;j<=n;j++) {
for(int i=1;i<=n;i++) {
if(i == j) g[i][j] = true;
else if(s[i] == s[j]) {
if(i+1>j-1||g[i+1][j-1]) g[i][j] = true;
}
}
}
f[0] = 0;
for(int i=1;i<=n;i++) {
for(int j=1;j<=i;j++) {
if(g[j][i]) {
f[i] = min(f[i], f[j-1]+1);
}
}
}
return f[n] - 1;
}
};