链接
https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2631
题解
把串正反分别哈希一下,
判断回文串
f[i]=min{f[j-1]+1} (s[j…i]是回文串)
代码
//哈希、DP
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cctype>
#define maxn 1010
#define inf (1ll<<60)
#define cl(x) memset(x,0,sizeof(x))
#define mod 1000000007ll
#define ll long long
#define base 4894651ll
using namespace std;
ll n, hash1[maxn], hash2[maxn], b[maxn], _b[maxn], f[maxn];
char s[maxn];
ll fastpow(ll a, ll b)
{
ll ans=1, t=a;
for(;b;b>>=1,t=t*t%mod)if(b&1)ans=ans*t%mod;
return ans;
}
void preprocess()
{
int i;
b[0]=_b[0]=1;
for(i=1;i<maxn;i++)b[i]=b[i-1]*base%mod;
for(i=1;i<maxn;i++)_b[i]=fastpow(b[i],mod-2);
}
void init()
{
int i;
scanf("%s",s+1);
n=strlen(s+1);
for(i=1;i<=n;i++)hash1[i]=(hash1[i-1]+s[i]*b[i-1])%mod, hash2[i]=(hash2[i-1]+s[n-i+1]*b[i-1])%mod;
}
ll gethash(ll hash[], ll l, ll r){return ((hash[r]-hash[l-1])*_b[l-1]%mod+mod)%mod;}
void dp()
{
ll i, j;
for(i=1;i<=n;i++)
{
f[i]=inf;
for(j=1;j<=i;j++)if(gethash(hash1,j,i)==gethash(hash2,n-i+1,n-j+1))f[i]=min(f[i],f[j-1]+1);
}
printf("%lld\n",f[n]);
}
int main()
{
ll T;
preprocess();
for(scanf("%lld",&T);T--;)
{
init();
dp();
}
return 0;
}