UVA 11584 Partitioning by Palindromes

来源:互联网 发布:js canvas drawimage 编辑:程序博客网 时间:2024/05/29 04:47

【题目大意】
把一个字符串切割成尽量少的回文串。


【题目分析】
很裸的dp,f[i]=min(f[i],f[j]+1(i..j是回文串)).
如果这样写的话,加入判断,n^3.
倘若加入预处理就是2*n^2. 大约在20~30ms之间
我看到了一些10ms的代码,他们把动态规划和预处理合在一起进行。
给一个virtual judge 的链接。代码在这里
然后就是我的方法,用manacher进行处理,就变成了n+n^2。理论上是比上一种方法好的


【代码】

#include <cstdio>#include <string>#include <cstring>#include <iostream>#include <algorithm>using namespace std;int r[2010],dp[2010];char s[2010],ch[2010];inline int min(int a,int b){return a>b?b:a;}inline bool pd(int l,int e){    if ((r[l+e]*2-1)/2>=e-l+1) return true;    else return false;}int main(){    int tt;    scanf("%d",&tt);    while (tt--)    {        memset(r,0,sizeof r);        memset(dp,0x3f,sizeof dp);        memset(r,0,sizeof r);        dp[0]=0;        scanf("%s",ch+1);        int l=strlen(ch+1);        s[1]='#';s[2*l+2]='#';        for (int i=1;i<=l;++i)        {            s[i*2]=ch[i];            s[i*2|1]='#';        }        int id=0,mx=0;        r[0]=1;        for (int i=1;i<=2*l+1;++i){            if (mx>i) r[i]=min(r[2*id-i],mx-i);            else r[i]=1;            while (s[i-r[i]]==s[i+r[i]]) r[i]++;            if (i+r[i]>mx) mx=i+r[i],id=i;        }        for (int i=1;i<=l;++i)            for (int j=1;j<=i;++j)                if (pd(j,i)) dp[i]=min(dp[i],dp[j-1]+1);        printf("%d\n",dp[l]);    }}
0 0