zoukankan      html  css  js  c++  java
  • HDU 3689 Infinite monkey theorem ——(自动机+DP)

      这题由于是一个单词,其实直接kmp+dp也无妨。建立自动机当然也是可以的。设dp[i][j]表示匹配到第i个字母的时候,在单词中处于第j个位置的概率,因此最终的答案是dp[0~m][len],m是输入的长度,len是单词的长度。转移方程见代码,即在一个节点的位置时,枚举下一步的走法,乘以这种走法的概率即是对下一个状态的概率贡献。

      其实自动机的fail指针跳转的位置即是kmp中nxt数组跳转的位置。

      代码如下:

     1     {
     2         while(j && word[j+1] != word[i]) j = nxt[j];
     3         if(word[j+1] == word[i]) j++;
     4         nxt[i] = j;
     5     }
     6 }
     7 
     8 int main()
     9 {
    10     while(scanf("%d%d",&n,&m) == 2)
    11     {
    12         if(n==0 && m==0) break;
    13         char s[5];
    14         for(int i=1;i<=n;i++)
    15         {
    16             scanf("%s%lf",s,p+i);
    17             c[i] = s[0];
    18         }
    19         scanf("%s",word+1);
    20         len = strlen(word+1);
    21         get_nxt();
    22         memset(dp,0,sizeof dp);
    23         dp[0][0] = 1.0;
    24         for(int i=0;i<m;i++)
    25         {
    26             for(int j=0;j<len;j++)
    27             {
    28                 for(int k=1;k<=n;k++)
    29                 {
    30                     int pos = j;
    31                     while(pos && word[pos+1] != c[k]) pos = nxt[pos];
    32                     if(word[pos+1] == c[k]) pos++;
    33                     dp[i+1][pos] += dp[i][j] * p[k];
    34                 }
    35             }
    36         }
    37         double ans = 0.0;
    38         for(int i=0;i<=m;i++) ans += dp[i][len];
    39         printf("%.2f%%
    ",ans*100.0);
    40     }
    41     return 0;
    42 }
    kmp+dp
      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 const int MAX_Tot = 100 + 50;
      4 
      5 int n,m,len;
      6 double p[30];
      7 char word[20];
      8 int nxt[20];
      9 double dp[1005][20];
     10 
     11 struct Aho
     12 {
     13     struct state
     14     {
     15         int nxt[26];
     16         int fail,cnt;
     17     }stateTable[MAX_Tot];
     18 
     19     int size;
     20 
     21     queue<int> que;
     22 
     23     void init()
     24     {
     25         while(que.size()) que.pop();
     26         for(int i=0;i<MAX_Tot;i++)
     27         {
     28             memset(stateTable[i].nxt,0,sizeof(stateTable[i].nxt));
     29             stateTable[i].fail = stateTable[i].cnt = 0;
     30         }
     31         size = 1;
     32     }
     33 
     34     void insert(char *s)
     35     {
     36         int n = strlen(s);
     37         int now = 0;
     38         for(int i=0;i<n;i++)
     39         {
     40             char c = s[i];
     41             if(!stateTable[now].nxt[c-'a'])
     42                 stateTable[now].nxt[c-'a'] = size++;
     43             now = stateTable[now].nxt[c-'a'];
     44         }
     45         stateTable[now].cnt++;
     46     }
     47 
     48     void build()
     49     {
     50         stateTable[0].fail = -1;
     51         que.push(0);
     52 
     53         while(que.size())
     54         {
     55             int u = que.front();que.pop();
     56             for(int i=0;i<26;i++)
     57             {
     58                 if(stateTable[u].nxt[i])
     59                 {
     60                     if(u == 0) stateTable[stateTable[u].nxt[i]].fail = 0;
     61                     else
     62                     {
     63                         int v = stateTable[u].fail;
     64                         while(v != -1)
     65                         {
     66                             if(stateTable[v].nxt[i])
     67                             {
     68                                 stateTable[stateTable[u].nxt[i]].fail = stateTable[v].nxt[i];
     69                                 break;
     70                             }
     71                             v = stateTable[v].fail;
     72                         }
     73                         if(v == -1) stateTable[stateTable[u].nxt[i]].fail = 0;
     74                     }
     75                     que.push(stateTable[u].nxt[i]);
     76                 }
     77                 /*****建立自动机nxt指针*****/
     78                 else
     79                 {
     80                     if(u == 0) stateTable[u].nxt[i] = 0;
     81                     else
     82                     {
     83                         int p = stateTable[u].fail;
     84                         while(p != -1 && stateTable[p].nxt[i] == 0) p = stateTable[p].fail;
     85                         if(p == -1) stateTable[u].nxt[i] = 0;
     86                         else stateTable[u].nxt[i] = stateTable[p].nxt[i];
     87                     }
     88                 }
     89                 /*****建立自动机nxt指针*****/
     90             }
     91         }
     92     }
     93 }aho;
     94 
     95 int main()
     96 {
     97     while(scanf("%d%d",&n,&m) == 2)
     98     {
     99         if(n==0 && m==0) break;
    100         aho.init();
    101         char s[5];
    102         memset(p,0,sizeof p);
    103         for(int i=1;i<=n;i++)
    104         {
    105             double t;
    106             scanf("%s%lf",s,&t);
    107             p[s[0]-'a'] = t;
    108         }
    109         scanf("%s",word+1);
    110         aho.insert(word+1); aho.build();
    111         memset(dp,0,sizeof dp);
    112         dp[0][0] = 1.0;
    113         int sz = aho.size-1;
    114         for(int i=0;i<m;i++)
    115         {
    116             for(int j=0;j<sz;j++)
    117             {
    118                 for(int k=0;k<26;k++)
    119                 {
    120                     int v = aho.stateTable[j].nxt[k];
    121                     dp[i+1][v] += dp[i][j] * p[k];
    122                 }
    123             }
    124         }
    125         double ans = 0.0;
    126         for(int i=0;i<=m;i++) ans += dp[i][sz];
    127         printf("%.2f%%
    ",ans*100.0);
    128     }
    129     return 0;
    130 }
    自动机+dp
  • 相关阅读:
    [51nod 1129] 字符串最大值(kmp)
    P3391 【模板】文艺平衡树(Splay)
    次大公约数
    青蛙的约会
    [HNOI2002]营业额统计
    GYM 100741A Queries
    P3370 【模板】字符串哈希
    P3369 【模板】普通平衡树(Treap/SBT)
    05:LGTB 与偶数
    简单计算器
  • 原文地址:https://www.cnblogs.com/zzyDS/p/6295781.html
Copyright © 2011-2022 走看看