• poj1625Censored!(AC自动机+dp)


    链接

    第一次做这种题目,参考了下题解,相当于把树扯直了做DP,估计这一类题都是这个套路吧。

    状态方程dp[i][next] = dp[i][next]+dp[i][j] ;dp[i][j]表示长度为i的第J个结点的时候满足题意的num,next为当前j点所能走到的下一个合法的结点。

    需要用高精度,看到一些规范的高精度写法,觉得不错,有空整理下来。

    不知道是不是我理解错了,按理说字符串病毒长度不应超过10.。但开到55依旧RE,开550AC。。。

      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 110
     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 = 110;
     18 const int BASE = 10000;
     19 const int DIG = 4;
     20 char s[N*100],vir[550];
     21 int id[2024];
     22 struct bignum
     23 {
     24      int a[110],len;
     25      bignum()
     26      {
     27          memset(a,0,sizeof(a));
     28          len = 1;
     29      }
     30      bignum(int v)
     31      {
     32          memset(a,0,sizeof(a));
     33          len = 0;
     34          do
     35          {
     36              a[len++] = v%BASE;
     37              v/=BASE;
     38          }while(v);
     39      }
     40      /*bignum(const char s[])
     41      {
     42          memset(a,0,sizeof(a));
     43          int k = strlen(s);
     44          len = k/DIG;
     45          if(k%DIG) len++;
     46          int cnt = 0;
     47          for(int i = k-1;  i >= 0 ; i-=DIG)
     48          {
     49              int t = 0;
     50              int kk = i-DIG+1;
     51              if(kk<0) kk =0;
     52              for(int j = kk ; j <= i ; j++)
     53              t = t*10+s[j]-'0';
     54              a[cnt++] = t;
     55          }
     56      }*/
     57      bignum operator + (const bignum &b)const
     58      {
     59          bignum res;
     60          res.len = max(len,b.len);
     61          int i;
     62          for(i = 0 ; i < res.len ;i ++)
     63          res.a[i] = 0;
     64          for(i = 0 ; i < res.len ; i++)
     65          {
     66              res.a[i] += ((i<len)?a[i]:0)+((i<b.len)?b.a[i]:0);
     67              res.a[i+1] += res.a[i]/BASE;
     68              res.a[i] = res.a[i]%BASE;
     69          }
     70          if(res.a[res.len]>0) res.len++;
     71          return res;
     72      }
     73      void output()
     74      {
     75          printf("%d",a[len-1]);
     76          for(int i = len-2 ; i >=0 ; i--)
     77          printf("%04d",a[i]);
     78          printf("
    ");
     79      }
     80 }dp[110][110];
     81 class AC
     82 {
     83     private:
     84     int ch[N][child_num];
     85     int Q[N];
     86     int val[N];
     87     int fail[N];
     88     //int id[N];
     89     int sz;
     90     public :
     91     void init()
     92     {
     93         fail[0] = 0;
     94         //for(int i = 0 ;i < child_num-32 ; i++)
     95         //id[i+32] = i;
     96     }
     97     void reset()
     98     {
     99         memset(val,0,sizeof(val));
    100         memset(fail,0,sizeof(fail));
    101         memset(ch[0],0,sizeof(ch[0]));
    102         sz = 1;
    103     }
    104     void insert(char *a,int key)
    105     {
    106         int k = strlen(a),p = 0;
    107         for(int i = 0 ; i < k ;i++)
    108         {
    109             int d = id[a[i]];
    110             if(ch[p][d]==0)
    111             {
    112                 memset(ch[sz],0,sizeof(ch[sz]));
    113                 ch[p][d] = sz++;
    114             }
    115             p = ch[p][d];
    116         }
    117         val[p] = key;
    118     }
    119     void construct(int n)
    120     {
    121         int i,head=0,tail = 0;
    122         for(i = 0; i < n ; i++)
    123         {
    124             if(ch[0][i])
    125             {
    126                 Q[tail++] = ch[0][i];
    127                 fail[ch[0][i]] = 0;
    128             }
    129         }
    130         while(head!=tail)
    131         {
    132             int u = Q[head++];
    133             val[u]|=val[fail[u]];
    134             for(i = 0 ; i < n ; i++)
    135             {
    136                 if(ch[u][i])
    137                 {
    138                     Q[tail++] = ch[u][i];
    139                     fail[ch[u][i]] = ch[fail[u]][i];
    140                 }
    141                 else ch[u][i] = ch[fail[u]][i];
    142             }
    143         }
    144     }
    145     void work(int m,int n)
    146     {
    147         int i,j,g;
    148         for(i = 1; i <= m ;i++)
    149             for(j = 0 ;j <= sz; j++)
    150             dp[i][j] = bignum(0);
    151         dp[0][0] = bignum(1);
    152         for(i = 0 ; i < m ;i++)
    153         {
    154             for(j = 0 ; j < sz ;j++)
    155             for(g = 0 ; g < n ; g++)
    156             if(!val[ch[j][g]])
    157             {
    158                 dp[i+1][ch[j][g]]=dp[i+1][ch[j][g]]+dp[i][j];
    159             }
    160         }
    161         bignum ans = bignum(0);
    162         for(j = 0 ;j < sz ; j++)
    163         ans=ans+dp[m][j];
    164         ans.output();
    165     }
    166 }ac;
    167 int main()
    168 {
    169     int n,m,i,p;
    170     ac.init();
    171     while(cin>>n>>m>>p)
    172     {
    173         cin>>s;
    174         for(i = 0 ; i < n; i++)
    175         id[s[i]] = i;
    176         ac.reset();
    177         for(i = 1;i <= p; i++)
    178         {
    179             scanf("%s",vir);
    180             ac.insert(vir,1);
    181         }
    182         ac.construct(n);
    183         ac.work(m,n);
    184     }
    185     return 0;
    186 }
    View Code
  • 相关阅读:
    Codeforces Round 718C Sasha and Array (矩阵线段树)
    Ural Timus 1009 K-based Numbers (dp+矩阵快速幂+快速乘)
    CPE常用指令
    Error opening terminal:xterm解决方法
    编译MT7620n NFS文件系统
    ubuntu中把dash链接变成bash
    USB相关
    HI3515海思开发板移植3G模块笔记
    openwrt的一些琐事
    snprintf拷贝字符串
  • 原文地址:https://www.cnblogs.com/shangyu/p/3730815.html
Copyright © 2020-2023  润新知