用trie树匹配字串,树上套个dp即可
1 /*By SilverN*/ 2 #include<iostream> 3 #include<cstdio> 4 #include<cmath> 5 #include<cstring> 6 #include<algorithm> 7 #define LL long long 8 using namespace std; 9 const int mxn=400010; 10 const int mod=20071027; 11 struct trie{ 12 int a[mxn][26]; 13 int end[mxn]; 14 int cnt; 15 void insert(char s[]){ 16 int len=strlen(s); 17 int now=1; 18 for(int i=0;i<len;++i){ 19 if(!a[now][s[i]-'a'])a[now][s[i]-'a']=++cnt; 20 now=a[now][s[i]-'a']; 21 } 22 end[now]++; 23 } 24 }; 25 trie t; 26 char s[mxn]; 27 char c[mxn]; 28 int n; 29 int f[mxn]; 30 void dp(int cas){ 31 memset(f,0,sizeof f); 32 int len=strlen(s+1); 33 int i,j; 34 f[len+1]=1; 35 for(i=len;i;--i){ 36 int now=1; 37 for(j=i;j<=len;++j){ 38 now=t.a[now][s[j]-'a']; 39 if(!now)break; 40 if(t.end[now]) 41 f[i]=(f[i]+f[j+1])%mod; 42 } 43 // printf("f[%d]==%d ",i,f[i]); 44 } 45 printf("Case %d: %d ",cas,f[1]); 46 return; 47 } 48 int main(){ 49 int cas=0; 50 while(scanf("%s",s+1)!=EOF){ 51 memset(t.a,0,sizeof t.a); 52 memset(t.end,0,sizeof t.end); 53 t.cnt=1; 54 int i,j; 55 scanf("%d",&n); 56 for(i=1;i<=n;++i){ 57 scanf("%s",c); 58 t.insert(c); 59 } 60 dp(++cas); 61 } 62 return 0; 63 }