• hdu 2825


    AC自动机+DP,AC自动机还是把字符串按后缀分类,每个节点记录串的状态为本节点时会包含哪几个所给出的字符串。ans[i][j][k]表示长度为i状态为j包含的所给出的字符串为k(二进制,每一位1,0表示有没有第i个字符串)的字符串的个数。

      1     #include <iostream>
      2     #include <cstdio>
      3     #include <cstring>
      4     #include <queue>
      5     #define LL long long
      6     using namespace std;
      7     const int mod=20090717;
      8     const int maxn=11;
      9     int ch[maxn*11][26],val[maxn*11],f[maxn*11];
     10     int ans[26][maxn*11][1<<(10)],num[1<<(10)];
     11     int n,m,q,tot,tot2;
     12     void Insert(char *s)
     13     {
     14         int u=0,len=strlen(s),i,tv;
     15         for(i=0;i<len;i++)
     16         {
     17             tv=s[i]-'a';
     18             if(!ch[u][tv]) ch[u][tv]=tot++;
     19             u=ch[u][tv];
     20         }
     21         val[u]=1<<(tot2++);
     22     }
     23     void getFail()
     24      {
     25          queue<int> q;
     26          f[0]=0;
     27          int i,u;
     28          for(i=0;i<26;i++)
     29          {
     30              u=ch[0][i];
     31              if(u)
     32              {
     33                  f[u]=0;
     34                  q.push(u);
     35              }
     36          }
     37          int v,r;
     38          while(!q.empty())
     39          {
     40              r=q.front();q.pop();
     41              for(i=0;i<26;i++)
     42              {
     43                  u=ch[r][i];
     44                  if(!u) {ch[r][i]=ch[f[r]][i]; }
     45                  else
     46                  {
     47                  q.push(u);
     48                  v=f[r];
     49                  while(v&&!ch[v][i]) v=f[v];
     50                  f[u]=ch[v][i];
     51                  val[u]|=val[f[u]];
     52                  }
     53              }
     54          }
     55      }
     56     int main()
     57     {
     58       //  freopen("1.txt","r",stdin);
     59         num[0]=0;
     60         int i;
     61         for(i=1;i<(1<<10);i++) num[i]=num[i>>1] +(i&1);
     62         while(scanf("%d%d%d",&n,&m,&q))
     63         {
     64             if(!n&&!m&&!q) break;
     65             char s[15];
     66             memset(ch,0,sizeof(ch));
     67             memset(val,0,sizeof(val));
     68             tot=1;tot2=0;
     69             for(i=0;i<m;i++)
     70             {
     71                 scanf("%s",s);
     72                 Insert(s);
     73             }
     74             getFail();
     75             int j,k,w,v;
     76             int M=1<<m;
     77             for(i=0;i<=n;++i)
     78                 for(j=0;j<tot;++j)
     79                     for(k=0;k<M;++k)
     80                         ans[i][j][k]=0;
     81             ans[0][0][0]=1;
     82             for(i=0;i<n;++i)
     83             {
     84                 for(j=0;j<tot;++j)
     85                 {
     86                     for(k=0;k<M;++k)
     87                     {
     88                        if(!ans[i][j][k]) continue;
     89                         for(w=0;w<26;w++)
     90                         {
     91                             v=ch[j][w];
     92                             ans[i+1][v][k|val[v]]=(ans[i+1][v][k|val[v]]+ans[i][j][k])%mod;
     93                         }
     94                     }
     95                 }
     96             }
     97             int sum=0;
     98             for(i=0;i<tot;++i)
     99             {
    100                 for(j=0;j<(1<<m);++j)
    101                 {
    102                     if(num[j]>=q)
    103                         sum=(sum+ans[n][i][j])%mod;
    104                 }
    105             }
    106             printf("%d\n",sum);
    107         }
    108         return 0;
    109     }
  • 相关阅读:
    JSONP
    函数式编程
    Cookie
    IE userData
    Web Storage
    前端学PHP之会话Session
    数据结构之归并排序
    数据结构之冒泡排序
    数据结构之插入排序
    数据结构之选择排序
  • 原文地址:https://www.cnblogs.com/lj030/p/3102579.html
Copyright © 2020-2023  润新知