class Solution {
public:
int minCut(string s) {
//先求解小段的子序列
vector<vector<int>> dp(s.length(), vector<int>(s.length())); //存放最小切割数
vector<vector<bool>> p(s.length(), vector<bool>(s.length(), false)); //存放是否是回文
for (int t = 0;t <= s.length();t++) {
for (int i = 0, j = t;j<s.length();i++, j++) {
dp[i][j] = compCut(i, j, s, p, dp);
}
}
return dp[0][s.length() - 1];
}
// 状态转移方程的实现
int compCut(int i, int j, string &s, vector<vector<bool>> &p, vector<vector<int>> &dp) {
if (s[i] == s[j] && (j - i < 2 || p[i + 1][j - 1])) {
p[i][j] = true;
return 0;
}
int min = s.length();
for (int k = i; k < j; ++k) {
int a = dp[i][k];
int b = dp[k + 1][j];
a = a + b + 1;
min = min<a ? min : a;
}
return min;
}
};
/*
class Solution {
public:
int minCut(string s) {
vector<int> dp(s.length() + 1);
vector<vector<bool>> p(s.length(), vector<bool>(s.length(), false));
dp[s.length()] = -1;//确保dp[s.length()-1]=0
for (int i = s.length() - 1; i >= 0; --i) {
//下面i==j时肯定是回文,一定会被替换掉,所以不用去初始化为s.length()-i-1
dp[i] = INT_MAX;
for (int j = i; j < s.length(); ++j) {
if (s[i] == s[j] && (j - i < 2 || p[i+1][j-1])) {
dp[i] = min(dp[i], dp[j + 1] + 1);
p[i][j] = true;
}
}
}
return dp[0];
}
};
*/