定义函数
D[i,n] = 区间[i,n]之间最小的cut数,n为字符串长度
a b a b b b a b b a b a
i n
如果现在求[i,n]之间的最优解?应该是多少?简单看一看,至少有下面一个解
a b a b b b a b b a b a
i j j+1 n
此时 D[i,n] = min(D[i, j] + D[j+1,n]) i<=j <n。这是个二维的函数,实际写代码时维护比较麻烦。所以要转换成一维DP。如果每次,从i往右扫描,每找到一个回文就算一次DP的话,就可以转换为
D[i] = 区间[i,n]之间最小的cut数,n为字符串长度, 则,
D[i] = min(1+D[j+1] ) i<=j <n
有个转移函数之后,一个问题出现了,就是如何判断[i,j]是否是回文?每次都从i到j比较一遍?太浪费了,这里也是一个DP问题。
定义函数
P[i][j] = true if [i,j]为回文
那么
P[i][j] = str[i] == str[j] && P[i+1][j-1];
class Solution {
public:
int minCut(string s) {
if(s.size()==0)
return 0;
vector<vector<bool>>dp(s.size(),vector<bool>(s.size(),false));
vector<int>res(s.size()+1,INT_MAX);
res[0]=-1;
for(int i=0;i<s.size();i++)
dp[i][i]=true;
for(int i=1;i<=s.size();i++)
for(int j=0;j<i;j++)
{
if(s[i-1]==s[j]&&((i-j)<=2||dp[i-2][j+1]))
{
dp[i-1][j]=true;
res[i]=min(res[i],res[j]+1);
}
}
return res[s.size()];
}
};