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

Posted wdt1

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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;
}




以上是关于b_51_回文串划分(预处理+dp)的主要内容,如果未能解决你的问题,请参考以下文章

1154 回文串划分(DP+Manacher)

51nod 1154 dp

lightoj1044_区间dp

51Nod-1154 回文串划分

Palindrome Partitioning LightOJ - 1044(回文串最小分割数,O(n^2)预处理子串是否回文)

回文串划分