记忆化搜索,记录l和r之间的最大回文串数,因为还需要打印出来,所以再记录一下路径即可。
#include<bits/stdc++.h>
using namespace std;
const int N=1100;
int d[N][N],x[N][N],y[N][N];
char s[N],a[N];
int dfs(int l,int r)
{
if(l>r) return 0;
if(l==r) return d[l][r]=1;
if(d[l][r]!=0) return d[l][r];
int sum=0,ti=-1,tj=-1;
for(int i=l+1;i<=r-1;i++)
{
for(int j=r-1;j>=i&&j>=tj;j--)
{
if(s[i]==s[j])
{
int len=dfs(i,j);
if(len>sum)
{
sum=len;
ti=i;tj=j;
}
if(len==sum&&s[i]<s[ti])
{
ti=i;tj=j;
}
}
}
}//cout<<l<<" "<<r<<" "<<ti<<" "<<tj<<" "<<sum<<endl;
x[l][r]=ti;y[l][r]=tj;
return d[l][r]=sum+2;
}
int main()
{
while(~scanf("%s",s+1))
{
memset(d,0,sizeof(d));
memset(x,-1,sizeof(x));
memset(y,-1,sizeof(y));
int n=strlen(s+1);
s[0]='a';s[n+1]='a';
dfs(0,n+1);
int l=x[0][n+1],ll,rr,r=y[0][n+1];
int m=0;
while(1)
{//cout<<l<<" "<<r<<endl;
if(l<0||r<0||l>r) break;
if(l==r)
{
a[m++]=s[l];
for(int i=m-2;i>=0;i--) a[m++]=a[i];
break;
}
if(l+1==r)
{
a[m++]=s[l];
for(int i=m-1;i>=0;i--) a[m++]=a[i];
break;
}
a[m++]=s[l];
ll=l;rr=r;
l=x[ll][rr];
r=y[ll][rr];
}
for(int i=0;i<m;i++) printf("%c",a[i]);
printf("\n");
}
}
/*
aabbaabb
computer
abzla
samhita
*/