bzoj 1030 fail树dp

     dp[i][j][0]代表当前匹配到i号点走了j步且没到过单词节点,1代表到过,直接转移。

     

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<queue>
 6 #define mod 10007
 7 #define N 6005
 8 using namespace std;
 9 int ch[N][26];int cnt;int f[N];
10 int n,m;
11 char s[105];
12 bool ok[N];
13 void in()
14 {
15     int l=strlen(s);int now=0;
16     for(int i=0;i<l;i++)
17     {
18         int y=s[i]-'A';
19         if(!ch[now][y])ch[now][y]=++cnt;
20         now=ch[now][y];
21     }
22     ok[now]=1;
23 }
24 queue<int>q;
25 void fail()
26 {
27     for(int i=0;i<26;i++)
28     {
29         if(ch[0][i])
30         {
31             q.push(ch[0][i]);
32         }
33     }
34     while(!q.empty())
35     {
36         int tmp=q.front();q.pop();
37         for(int i=0;i<26;i++)
38         {
39             int u=ch[tmp][i];
40             if(!u)
41             {
42                 ch[tmp][i]=ch[f[tmp]][i];continue;
43             }
44             q.push(u);f[u]=ch[f[tmp]][i];
45             if(ok[f[u]])ok[u]=1;
46         }
47     }
48 }
49 int dp[6005][105][2];
50 void dpp()
51 {
52     dp[0][0][0]=1;
53     for(int i=0;i<m;i++)
54     {
55         for(int j=0;j<=cnt;j++)
56         {
57             for(int k=0;k<26;k++)
58             {
59                 if(ok[ch[j][k]])
60                 {
61                     dp[ch[j][k]][i+1][1]+=(dp[j][i][1]+dp[j][i][0]);
62                     dp[ch[j][k]][i+1][1]%=mod;
63                 }
64                 else 
65                 {
66                     dp[ch[j][k]][i+1][1]+=dp[j][i][1];dp[ch[j][k]][i+1][1]%=mod;
67                     dp[ch[j][k]][i+1][0]+=dp[j][i][0];dp[ch[j][k]][i+1][0]%=mod;
68                 }
69             }
70         }
71     }
72     return ;
73 }
74 int main()
75 {
76     scanf("%d%d",&n,&m);
77     for(int i=1;i<=n;i++)
78     {
79         scanf("%s",s);in();
80     }
81     fail();
82     dpp();
83     int ans=0;
84     for(int i=0;i<=cnt;i++)
85     {
86         ans=(ans+dp[i][m][1])%mod;
87     }
88     cout<<ans<<endl;
89     return 0;
90 }

 

posted @ 2016-12-09 14:23  SD_le  阅读(137)  评论(0编辑  收藏
重置按钮