传送门biu~
枚举长度是
|T|
|
T
|
因子的子串
t
t
进行判断。
表示子串
T[i,j]
T
[
i
,
j
]
能否合法由t产生。
转移时在末尾加长度为
|t|
|
t
|
倍数的区间或者匹配一位
t(j−i)mod|t|
t
(
j
−
i
)
m
o
d
|
t
|
.
#include<bits/stdc++.h>
#define N 205
using namespace std;
char s[N],t[N],ans[N];
int n,len,flag,f[N][N];
int dp(int i,int j){
if(i>j) return 1;
if(~f[i][j]) return f[i][j];
for(int k=j-len;k>=i;k-=len)
if(dp(i,k) && dp(k+1,j)) return f[i][j]=1;
if(s[j]==t[(j-i)%len+1]) return f[i][j]=dp(i,j-1);
return f[i][j]=0;
}
int main(){
scanf("%s",s+1);n=strlen(s+1);
for(len=1;len<=n;++len){
if(n%len) continue;
for(int i=1;i+len-1<=n;++i){
for(int j=1;j<=len;++j) t[j]=s[i+j-1];
memset(f,-1,sizeof f);
if(dp(1,n)){
if(flag){
for(int j=1;j<=len;++j){
if(ans[j]<t[j]) break;
if(t[j]<ans[j]){
for(int k=1;k<=len;++k) ans[k]=t[k];
break;
}
}
}
else{
flag=true;
for(int j=1;j<=len;++j) ans[j]=t[j];
}
}
}
if(flag){
for(int i=1;i<=len;++i) printf("%c",ans[i]);
return 0;
}
}
}