题目链接:https://ac.nowcoder.com/acm/contest/549/B?&headNav=acm
1.中间枚举(向两边扩展)
2.dp(最外层枚举长度,dp[i][j],i到j区间内的最优解)
3.Manacher算法 参考链接(https://www.cnblogs.com/z360/p/6375514.html)
附上三个代码:
#include <bits/stdc++.h>
#define LL long long
using namespace std;
string s;
int main()
{
string t;
cin>>t;
s=t+t;
int len=s.length();
int maxi=1;
for(int i=0;i<len;i++)
{
int mid=i;
int u,v;
u=mid-1;v=mid+1;
int tem=1;
if(u>=0&&s[u]==s[mid])
{
u--;
tem=2;
}
else if(v<len&&s[v]==s[mid])
{
v++;
tem=2;
}
for(;u>=0&&v<len&&u<v;u--,v++)
{
if(s[u]==s[v])
{
tem+=2;
}
else
break;
}
maxi=max(tem,maxi);
}
cout << min(maxi,len/2) << endl;
return 0;
}
#include <bits/stdc++.h>
#define LL long long
using namespace std;
const int maxn=10001;
bool dp[maxn][maxn];
string s;
void init()
{
memset(dp,false,sizeof(dp));
for(int i=0;i<maxn;i++)
{
dp[i][i]=true;
}
}
int main()
{
string t;
cin>>t;
s=t+t;
int len=s.length();
init();
int maxi=1;
for(int k=2;k<=len/2;k++)
{
for(int u=0;u+k-1<len;u++)
{
int v=u+k-1;
if(k==2)
{
if(s[u]==s[v])
{
dp[u][v]=true;
maxi=max(maxi,2);
}
continue;
}
if(dp[u+1][v-1]==1&&s[u]==s[v])
{
dp[u][v]=true;
maxi=max(maxi,v-u+1);
}
}
}
cout << min(maxi,len/2) << endl;
return 0;
}
#include<bits/stdc++.h>
using namespace std;
const int maxn=5005;
string tt;
int Len[maxn*2];
int main()
{
cin>>tt;
int len=tt.length();
int ans=0;
for(int u=0;u<len;u++)
{
string a=tt.substr(0,u);
string b=tt.substr(u);
string cc="";
cc+=b;
cc+=a;
string s=cc;
string z="";
z+='$';
for(int i=1;i<=2*len;i+=2)
{
z+='#';
z+=s[i/2];
}
z+='#';
z+='%';
int mx,maxi,po;
po=maxi=0;
mx=1;
for(int i=1;i<=2*len+1;i++)
{
if(mx>i)
Len[i]=min(mx-i,Len[po-(i-po)]);
else
Len[i]=1;
while(z[i-Len[i]]==z[i+Len[i]])
Len[i]++;
if(Len[i]+i>mx)
{
mx=Len[i]+i;
po=i;
}
maxi=max(maxi,Len[i]);
}
ans=max(ans,maxi-1);
}
cout << ans << endl;
return 0;
}