• 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
    ",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
  • 相关阅读:
    poj2411 状压dp
    棋盘覆盖TYVJ1035(二分图最大匹配)
    poj3417
    无向图边双+缩点
    无向图点双+缩点
    bzoj1123(割点加路径统计)
    【BZOJ1178】会议中心(APIO2009)-贪心+倍增+set
    【BZOJ4650】优秀的拆分(NOI2016)-后缀数组+RMQ+差分
    【BZOJ4569】萌萌哒(SCOI2016)-并查集+倍增
    【BZOJ2208】连通数(JSOI2010)-SCC+DP+bitset
  • 原文地址:https://www.cnblogs.com/shangyu/p/3750798.html
Copyright © 2020-2023  润新知