题目描述
思路分析
区间dp+线性dp
f
[
i
]
[
j
]
:
[
i
,
j
]
f[i][j]:[i,j]
f[i][j]:[i,j]是否是回文串
f
[
i
]
[
j
]
=
s
[
i
]
=
=
s
[
j
]
a
n
d
(
i
+
1
>
=
j
∣
∣
f
[
i
+
1
]
[
j
−
1
]
)
;
f[i][j]=s[i]==s[j]\ and\ (i+1>=j\ ||\ f[i+1][j-1]);
f[i][j]=s[i]==s[j] and (i+1>=j ∣∣ f[i+1][j−1]);
d
p
[
i
]
:
[
1
,
i
]
dp[i]:[1,i]
dp[i]:[1,i]的最小分割次数
d
p
[
i
]
=
m
i
n
(
d
p
[
j
−
1
]
+
1
)
(
f
[
j
]
[
i
]
a
n
d
1
<
=
j
<
=
i
)
;
dp[i]=min(dp[j-1]+1) (f[j][i]\ and\ 1<=j<=i);
dp[i]=min(dp[j−1]+1)(f[j][i] and 1<=j<=i);
代码实现
class Solution {
public:
int minCut(string s) {
int n=s.size();
s=" "+s;
vector<vector<bool>> f(n+1,vector<bool>(n+1));
vector<int> dp(n+1,1e9);
//区间dp预处理f
for(int len=1;len<=n;len++){
for(int l=1;l+len-1<=n;l++){
int r=l+len-1;
if(s[l]==s[r]&&(l+1>=r||f[l+1][r-1])) f[l][r]=true;
}
}
//线性dp
dp[0]=0;
for(int i=1;i<=n;i++){
for(int j=1;j<=i;j++){
if(f[j][i]) dp[i]=min(dp[i],dp[j-1]+1);
}
}
return dp[n]-1;
}
};