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

 

你可能感兴趣的:(AC自动机)