版权声明:本文为博主原创文章,未经博主允许必须转载。 https://blog.csdn.net/qq_35950004/article/details/88865841
题目
我刚写完占坑就让我打这玩意。
天道有轮回,苍天饶过谁。。。。。。
首先这个题,你得知道后缀自动机是一个DAG,所有子串都可以用这个DAG表示出来。
然后这个题,你得知道序列自动机也是个DAG,所有子序列都能用这个DAG表示出来。
然后就在这个DAG上BFS找最浅的在第一个DAG上合法,在第二个DAG上非法的点就行了。
以为是字典序最小,打DFS ,1WA
打BFS开
, MLE
又打回DFS搜完,TLE
加一发
记忆化,WA???
原来到DAG上同样的两个点的距离会不一样啊。
存了一个奇怪的东西,AC
NOIP选手表示。。。。。
AC Code:
#include<bits/stdc++.h>
#define maxn 4005
#define maxc 26
#define inf 0x3f3f3f3f
using namespace std;
int last,n,m;
int tr[4][maxn][maxc],fail[2][maxn],len[2][maxn],tot[2],nxt[maxc];
char A[maxn],B[maxn];
void ins(int c,int tr[maxn][maxc],int fail[maxn],int len[maxn],int &tot){
int p = last , q , cur = ++ tot;
len[last = cur] = len[p] + 1;
for(;p!=-1 && tr[p][c]==-1;p=fail[p]) tr[p][c]=cur;
if(p==-1) fail[cur] = 0;
else if(len[q=tr[p][c]] == len[p] + 1) fail[cur] = q;
else {
int cln = ++tot;
memcpy(tr[cln],tr[q],sizeof tr[q]),len[cln] = len[p] + 1;
for(;p!=-1 && tr[p][c]==q;p=fail[p]) tr[p][c] = cln;
fail[cln] = fail[q] , fail[q] = fail[cur] = cln;
}
}
map<int,int>mp[4][maxn];
int flag = 0;
int dfs(int rt1,int rt2,int tr[maxn][maxc],int tr2[maxn][maxc],int len,int tp){
if(rt1==-1) return inf;
if(rt2==-1) return len;
if(mp[tp][rt1].count(rt2)) return len+mp[tp][rt1][rt2];
int ret = inf;
for(int i=0;i<maxc;i++)
ret = min(ret , dfs(tr[rt1][i],tr2[rt2][i],tr,tr2,len+1,tp));
mp[tp][rt1][rt2] = ret - len;
return ret;
}
int main(){
//freopen("1.in","r",stdin);
//freopen("1.out","w",stdout);
scanf("%s",A);scanf("%s",B);
memset(tr,-1,sizeof tr);
n = strlen(A) , m = strlen(B);
fail[0][0] = fail[1][0] = -1;
for(int i=0;i<n;i++) ins(A[i]-'a',tr[0],fail[0],len[0],tot[0]);
last = 0;
for(int i=0;i<m;i++) ins(B[i]-'a',tr[1],fail[1],len[1],tot[1]);
memset(nxt,-1,sizeof nxt);
for(int i=n;i>=1;i--){
memcpy(tr[2][i],nxt,sizeof nxt);
nxt[A[i-1]-'a'] = i;
}
memcpy(tr[2][0],nxt,sizeof nxt);
memset(nxt,-1,sizeof nxt);
for(int i=m;i>=1;i--){
memcpy(tr[3][i],nxt,sizeof nxt);
nxt[B[i-1]-'a'] = i;
}
memcpy(tr[3][0],nxt,sizeof nxt);
int tmp;
printf("%d\n",(tmp=dfs(0,0,tr[0],tr[1],0,0)) == inf ? -1 : tmp);
printf("%d\n",(tmp=dfs(0,0,tr[0],tr[3],0,1)) == inf ? -1 : tmp);
printf("%d\n",(tmp=dfs(0,0,tr[2],tr[1],0,2)) == inf ? -1 : tmp);
printf("%d\n",(tmp=dfs(0,0,tr[2],tr[3],0,3)) == inf ? -1 : tmp);
}