标签:targe operator ace opened pac string printf val 题意
题目链接:UVALive - 4811 Growing Strings
题意:
给你n个字符串,问你最多能选出多少个字符串,使得s[i]是s[i+1]的子串。
题解:
先将所有的字符串插入AC自动机,将所有字符串按长度排序后,显然dp[i]=max{dp[j]}+1,其中s[j]是s[i]的子串。然后就完了。
1 #include<bits/stdc++.h> 2 #define mst(a,b) memset(a,b,sizeof(a)) 3 #define F(i,a,b) for(int i=(a);i<=(b);++i) 4 using namespace std; 5 6 const int AC_N=1e6+7,tyn=26; 7 int n,dp[AC_N],ed,ans; 8 char s[AC_N]; 9 struct Str 10 { 11 int l,len; 12 bool operator<(const Str &B)const{return len<B.len;} 13 }str[AC_N]; 14 15 struct AC_automation{ 16 int tr[AC_N][tyn],cnt[AC_N],Q[AC_N],fail[AC_N],tot; 17 inline int getid(char x){return x-‘a‘;} 18 void nw(){cnt[++tot]=0,fail[tot]=0;mst(tr[tot],0);} 19 void init(){tot=-1,fail[0]=-1,nw();} 20 void insert(char *s,int len,int idx,int x=0){ 21 for(int i=0,w;i<len;x=tr[x][w],i++) 22 if(!tr[x][w=getid(s[i])])nw(),tr[x][w]=tot; 23 cnt[x]=idx; 24 } 25 void build(int head=1,int tail=0){ 26 for(int i=0;i<tyn;i++)if(tr[0][i])Q[++tail]=tr[0][i]; 27 while(head<=tail)for(int x=Q[head++],i=0;i<tyn;i++) 28 if(tr[x][i])fail[tr[x][i]]=tr[fail[x]][i],Q[++tail]=tr[x][i]; 29 else tr[x][i]=tr[fail[x]][i]; 30 } 31 int ask(char *s,int l,int &ans){ 32 for(int x=0,i=0,w,j;i<l;i++){ 33 x=tr[x][w=getid(s[i])]; 34 for(j=x;j;j=fail[j])if(cnt[j])ans=max(ans,dp[cnt[j]]); 35 } 36 return ans; 37 } 38 }AC; 39 40 int main(){ 41 while(scanf("%d",&n),n) 42 { 43 ed=0,ans=1; 44 F(i,1,n) 45 { 46 scanf("%s",s+ed); 47 str[i]=Str{ed,(int)strlen(s+ed)}; 48 ed+=str[i].len; 49 } 50 sort(str+1,str+1+n); 51 AC.init(); 52 F(i,1,n)AC.insert(s+str[i].l,str[i].len,i); 53 AC.build(),dp[1]=1; 54 F(i,2,n) 55 { 56 dp[i]=0,AC.ask(s+str[i].l,str[i].len,dp[i]); 57 dp[i]++,ans=max(ans,dp[i]); 58 } 59 printf("%d\n",ans); 60 } 61 return 0; 62 }
UVALive - 4811 Growing Strings (AC自动机+dp)
标签:targe operator ace opened pac string printf val 题意
原文地址:http://www.cnblogs.com/bin-gege/p/7253899.html