首页 > 代码库 > hdu4758Walk Through Squares(ac自动机+dp)

hdu4758Walk Through Squares(ac自动机+dp)

链接

dp[x][y][node][sta] 表示走到在x,y位置node节点时状态为sta的方法数,因为只有2个病毒串,这时候的状态只有4种,根据可走的方向转移一下。

这题输入的是m、N,先列后行,因为输反了,WA了N次啊。。

  1 #include <iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<stdlib.h>
  6 #include<vector>
  7 #include<cmath>
  8 #include<queue>
  9 #include<set>
 10 using namespace std;
 11 #define N 210
 12 #define LL long long
 13 #define INF 0xfffffff
 14 const double eps = 1e-8;
 15 const double pi = acos(-1.0);
 16 const double inf = ~0u>>2;
 17 const int child_num = 2;
 18 const int mod = 1000000007;
 19 int n,m;
 20 int dis[2][2] = {1,0,0,1};
 21 char vir[150];
 22 class AC
 23 {
 24     private:
 25     int ch[N][child_num];
 26     int fail[N];
 27     int val[N];
 28     int Q[N];
 29     int id[128];
 30     int dp[N][110][110][4];
 31     int sz;
 32     public:
 33     void init()
 34     {
 35         fail[0] = 0;
 36         id[R] = 0;
 37         id[D] = 1;
 38     }
 39     void reset()
 40     {
 41         memset(val,0,sizeof(val));
 42         memset(ch[0],0,sizeof(ch[0]));
 43         sz = 1;
 44     }
 45     void insert(char *a,int key)
 46     {
 47         int p =0 ;
 48         for( ; *a ; a++)
 49         {
 50             int d = id[*a];
 51             if(ch[p][d]==0)
 52             {
 53                 memset(ch[sz],0,sizeof(ch[sz]));
 54                 ch[p][d] = sz++;
 55             }
 56             p = ch[p][d];
 57         }
 58         val[p] = (1<<(key-1));
 59     }
 60     void construct()
 61     {
 62         int i,head = 0,tail = 0;
 63         for(i = 0 ;  i < child_num;  i++)
 64         {
 65             if(ch[0][i])
 66             {
 67                 fail[ch[0][i]] = 0;
 68                 Q[tail++] = ch[0][i];
 69             }
 70         }
 71         while(tail!=head)
 72         {
 73             int u = Q[head++];
 74             val[u]|=val[fail[u]];
 75             for(i = 0; i < child_num ; i++)
 76             {
 77                 if(ch[u][i])
 78                 {
 79                     fail[ch[u][i]] = ch[fail[u]][i];
 80                     Q[tail++] = ch[u][i];
 81                 }
 82                 else ch[u][i] = ch[fail[u]][i];
 83             }
 84         }
 85     }
 86     void work()
 87     {
 88         int i,j,g;
 89         for(i = 0;i <= sz ;i++)
 90             for(j = 1; j <= n+1 ;j++)
 91                 for(g = 1; g <= m+1; g++)
 92                 for(int e =0 ; e  < 4 ; e++)
 93                 dp[i][j][g][e] = 0;
 94         //memset(dp,0,sizeof(dp));
 95 
 96         dp[0][1][1][0] = 1;
 97         for(j = 1; j <= n ;j ++)
 98             for(g = 1; g <= m ; g++)
 99             {
100                 for(i = 0 ;i < sz ; i++)
101                 for(int o = 0; o < 4 ; o++)
102                 for(int e = 0 ;e < child_num ;e++)
103                 {
104                     int tx = dis[e][0]+j;
105                     int ty = dis[e][1]+g;
106                     int p = ch[i][e];
107                     int pp = val[ch[i][e]];
108                     dp[p][tx][ty][o|pp] = (dp[p][tx][ty][o|pp]+dp[i][j][g][o])%mod;
109                 }
110             }
111         int ans = 0;
112         for(i = 0 ;i < sz ;i++)
113         ans = (ans+dp[i][n][m][3])%mod;
114         printf("%d\n",ans%mod);
115     }
116 }ac;
117 int main()
118 {
119     int t;
120     cin>>t;
121     ac.init();
122     while(t--)
123     {
124         ac.reset();
125         scanf("%d%d",&n,&m);
126         n++,m++;
127         scanf("%s",vir);
128         ac.insert(vir,1);
129         scanf("%s",vir);
130         ac.insert(vir,2);
131         ac.construct();
132         ac.work();
133     }
134     return 0;
135 }
View Code