zoukankan      html  css  js  c++  java
  • HDU 6086 Rikka with String ——(AC自动机 + DP)

      这是一个AC自动机+dp的问题,在中间的串的处理可以枚举中断点来插入自动机内来实现,具体参见代码。

      在这题上不止为何一直MLE,一直找不到结果(lyf相同写法的代码消耗内存较少),还好考虑到这题节点应该不会过多,可以少开一点节点数。

      代码如下:

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 //const int N = 5e4 + 5;
      4 //const int MAX_Tot = 6 * 20 * 20 + 6 * 20 + 100;
      5 const int MAX_Tot = 500;
      6 typedef long long ll;
      7 const int mod = 998244353;
      8 
      9 int T, n, L;
     10 void add(int &a, int b)
     11 {
     12     a += b;
     13     if(a >= mod) a -= mod;
     14     if(a < 0) a += mod;
     15 }
     16 struct Aho
     17 {
     18     struct state
     19     {
     20         int nxt[2];
     21         int fail;
     22         int ed, vis;
     23     }stateTable[MAX_Tot];
     24 
     25     int size;
     26 
     27     queue<int> que;
     28 
     29     void init()
     30     {
     31         while(que.size()) que.pop();
     32         for(int i=0;i<MAX_Tot;i++)
     33         {
     34             memset(stateTable[i].nxt,0,sizeof(stateTable[i].nxt));
     35             stateTable[i].fail = stateTable[i].ed = stateTable[i].vis = 0;
     36         }
     37         size = 1;
     38     }
     39 
     40     void insert(char *s,int which,int type)
     41     {
     42         int n = strlen(s);
     43         int now = 0;
     44         for(int i=0;i<n;i++)
     45         {
     46             char c = s[i];
     47             if(!stateTable[now].nxt[c-'0'])
     48                 stateTable[now].nxt[c-'0'] = size++;
     49             now = stateTable[now].nxt[c-'0'];
     50         }
     51         if(type == 1) stateTable[now].ed |= (1<<which);
     52         else stateTable[now].vis |= (1<<which);
     53     }
     54 
     55     void build()
     56     {
     57         stateTable[0].fail = -1;
     58         que.push(0);
     59 
     60         while(que.size())
     61         {
     62             int u = que.front();que.pop();
     63             for(int i=0;i<2;i++)
     64             {
     65                 if(stateTable[u].nxt[i])
     66                 {
     67                     if(u == 0) stateTable[stateTable[u].nxt[i]].fail = 0;
     68                     else
     69                     {
     70                         int v = stateTable[u].fail;
     71                         while(v != -1)
     72                         {
     73                             if(stateTable[v].nxt[i])
     74                             {
     75                                 stateTable[stateTable[u].nxt[i]].fail = stateTable[v].nxt[i];
     76                                 stateTable[stateTable[u].nxt[i]].ed |= stateTable[stateTable[stateTable[u].nxt[i]].fail].ed;
     77                                 stateTable[stateTable[u].nxt[i]].vis |= stateTable[stateTable[stateTable[u].nxt[i]].fail].vis;
     78                                 break;
     79                             }
     80                             v = stateTable[v].fail;
     81                         }
     82                         if(v == -1) stateTable[stateTable[u].nxt[i]].fail = 0;
     83                     }
     84                     que.push(stateTable[u].nxt[i]);
     85                 }
     86                 /*****建立自动机nxt指针*****/
     87                 else
     88                 {
     89                     if(u == 0) stateTable[u].nxt[i] = 0;
     90                     else
     91                     {
     92                         int p = stateTable[u].fail;
     93                         while(p != -1 && stateTable[p].nxt[i] == 0) p = stateTable[p].fail;
     94                         if(p == -1) stateTable[u].nxt[i] = 0;
     95                         else stateTable[u].nxt[i] = stateTable[p].nxt[i];
     96                     }
     97                 }
     98                 /*****建立自动机nxt指针*****/
     99             }
    100         }
    101     }
    102 
    103     int dp[110][MAX_Tot][1<<6];
    104     void solve()
    105     {
    106         memset(dp,0,sizeof dp);
    107         dp[0][0][0] = 1;
    108         for(int i=1;i<=L;i++)
    109         {
    110             for(int j=0;j<size;j++)
    111             {
    112                 for(int k=0;k<(1<<n);k++)
    113                 {
    114                     for(int ch=0;ch<2;ch++)
    115                     {
    116                         int now = stateTable[j].nxt[ch];
    117                         int nowS = stateTable[now].ed;
    118                         add(dp[i][now][k|nowS], dp[i-1][j][k]);
    119                     }
    120                 }
    121             }
    122         }
    123         int ans = 0;
    124         for(int i=0;i<size;i++)
    125         {
    126             for(int j=0;j<(1<<n);j++)
    127             {
    128                 if((stateTable[i].vis | j) == (1<<n)-1)
    129                 {
    130                     add(ans, dp[L][i][j]);
    131                 }
    132             }
    133         }
    134         printf("%d
    ",ans);
    135     }
    136 }aho;
    137 char s[50],t[50];
    138 void work(int fenge,int which)
    139 {
    140     int f = fenge;
    141     int you = fenge + 1;
    142     bool can = 1;
    143     int len = strlen(s);
    144     while(1)
    145     {
    146         if(s[fenge] == s[you])
    147         {
    148             can = 0;
    149             break;
    150         }
    151         fenge--; you++;
    152         if(fenge < 0 || you >= len) break;
    153     }
    154     if(!can) return ;
    155     fenge = f;
    156     if((fenge+1) * 2 <= len)
    157     {
    158         for(int i=0;i<len-(fenge+1);i++) t[i] = s[len-1-i] == '1' ? '0' : '1'; t[len-(fenge+1)] = 0;
    159         aho.insert(t,which,2);
    160     }
    161     else
    162     {
    163         for(int i=0;i<=fenge;i++) t[i] = s[i]; t[fenge+1] = 0;
    164         aho.insert(t,which,2);
    165     }
    166 }
    167 
    168 int main()
    169 {
    170     scanf("%d",&T);
    171     while(T--)
    172     {
    173         aho.init();
    174         scanf("%d%d",&n,&L);
    175         for(int i=0;i<n;i++)
    176         {
    177             scanf("%s",s);
    178             int len = strlen(s);
    179             aho.insert(s,i,1);
    180             for(int j=0;j<len;j++) t[j] = s[len-j-1] == '1' ? '0' : '1'; t[len] = 0;
    181             aho.insert(t,i,1);
    182             for(int j=0;j<len-1;j++) work(j,i);
    183         }
    184         aho.build();
    185         aho.solve();
    186     }
    187     return 0;
    188 }
  • 相关阅读:
    012.Nginx负载均衡
    011.Nginx防盗链
    010.Nginx正反代理
    009.Nginx缓存配置
    附007.Docker全系列大总结
    附024.Kubernetes全系列大总结
    008.Nginx静态资源
    007.Nginx虚拟主机
    006.Nginx访问控制
    005.Nginx配置下载站点
  • 原文地址:https://www.cnblogs.com/zzyDS/p/7404880.html
Copyright © 2011-2022 走看看