b_51_回文串划分(预处理+dp)

有一个字符串S,求S最少可以被划分为多少个回文串。例如:abbaabaa,有多种划分方式。
a|bb|aabaa - 3 个回文串
a|bb|a|aba|a - 5 个回文串
a|b|b|a|a|b|a|a - 8 个回文串

思路:f[i]表示子串s[0:i]最少可以划分为多少个回文串
优化:判断回文串可以用\(O(n^2)\)dp预处理

#include<bits/stdc++.h>
using namespace std;
const int N=5005;
int n,f[N],st[N][N];    //st[l][r]表示s[l:r]是否是回文;f[i]表示前i个字符可以最少划分为多少个回文串
char s[N];
void init_st() {
    memset(st,false,sizeof st), st[0][0]=1;
    for (int r=1; r<=n; r++)
    for (int l=1; l<=r; l++) {
        if (s[l]==s[r] && (r-l<2 || st[l+1][r-1]))
            st[l][r]=1;
    }
}
int main() {
    std::ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    cin>>s+1; 
    n=strlen(s+1), init_st();
    for (int i=1; i<=n; i++) f[i]=i;
    for (int i=1; i<=n; i++)
    for (int j=0; j<i; j++) if (st[j+1][i])
        f[i]=min(f[i], f[j]+1);
    cout<<f[n];
    return 0;
}
posted @ 2020-10-24 16:14  童年の波鞋  阅读(92)  评论(0编辑  收藏  举报