zoukankan      html  css  js  c++  java
  • UVa 11468 (AC自动机 概率DP) Substring

    将K个模板串构成一个AC自动机,那些能匹配到的单词节点都称之为禁止节点。

    然后问题就变成了在Tire树上走L步且不经过禁止节点的概率。

    根据全概率公式用记忆化搜索求解。

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <queue>
      4 using namespace std;
      5 
      6 const int maxnode = 500;
      7 const int sigma_size = 64;
      8 int idx[256];
      9 
     10 struct AhoCorasickAutomata
     11 {
     12     int ch[maxnode][sigma_size];
     13     int match[maxnode];
     14     int f[maxnode];
     15     int sz;
     16 
     17     void init() { sz = 1; memset(ch[0], 0, sizeof(ch[0])); }
     18 
     19     void insert(char* s)
     20     {
     21         int u = 0, n = strlen(s);
     22         for(int i = 0; i < n; i++)
     23         {
     24             int c = idx[s[i]];
     25             if(!ch[u][c])
     26             {
     27                 memset(ch[sz], 0, sizeof(ch[sz]));
     28                 match[sz] = 0;
     29                 ch[u][c] = sz++;
     30             }
     31             u = ch[u][c];
     32         }
     33         match[u] = 1;
     34     }
     35 
     36     void getFail()
     37     {
     38         queue<int> q;
     39         f[0] = 0;
     40         for(int c = 0; c < sigma_size; c++)
     41         {
     42             int u = ch[0][c];
     43             if(u) { f[u] = 0; q.push(u); }
     44         }
     45         while(!q.empty())
     46         {
     47             int r = q.front(); q.pop();
     48             for(int c = 0; c < sigma_size; c++)
     49             {
     50                 int u = ch[r][c];
     51                 if(!u) { ch[r][c] = ch[f[r]][c]; continue; }
     52                 q.push(u);
     53                 int v = f[r];
     54                 while(v && !ch[v][c]) v = f[v];
     55                 f[u] = ch[v][c];
     56                 match[u] |= match[f[u]];
     57             }
     58         }
     59     }
     60 }ac;
     61 
     62 int n;
     63 const int maxl = 100 + 10;
     64 char s[30][30];
     65 double prob[sigma_size];
     66 
     67 int vis[maxnode][maxl];
     68 double d[maxnode][maxl];
     69 
     70 double getProb(int u, int L)
     71 {
     72     if(L == 0) return 1.0;
     73     if(vis[u][L]) return d[u][L];
     74     vis[u][L] = 1;
     75     double& ans = d[u][L];
     76     ans = 0;
     77     for(int c = 0; c < n; c++)
     78         if(!ac.match[ac.ch[u][c]])
     79             ans += prob[c] * getProb(ac.ch[u][c], L-1);
     80     return ans;
     81 }
     82 
     83 int main()
     84 {
     85     //freopen("in.txt", "r", stdin);
     86 
     87     int T;
     88     scanf("%d", &T);
     89     for(int kase = 1; kase <= T; kase++)
     90     {
     91         int k, L;
     92         scanf("%d", &k);
     93         for(int i = 0; i < k; i++) scanf("%s", s[i]);
     94 
     95         scanf("%d", &n);
     96         for(int i = 0; i < n; i++)
     97         {
     98             char s1[9];
     99             scanf("%s%lf", s1, &prob[i]);
    100             idx[s1[0]] = i;
    101         }
    102 
    103         ac.init();
    104         for(int i = 0; i < k; i++) ac.insert(s[i]);
    105         ac.getFail();
    106         scanf("%d", &L);
    107         memset(vis, 0, sizeof(vis));
    108         printf("Case #%d: %.6f
    ", kase, getProb(0, L));
    109     }
    110 
    111     return 0;
    112 }
    代码君
  • 相关阅读:
    如何将baidu地图中的baidu logo 去掉
    漂亮的圆角文本框 CSS3实现
    jQuery数字加减插件
    腾迅股票数据接口 http/javascript
    JS复制内容到剪贴板(兼容FF/Chrome/Safari所有浏览器)
    关于编写性能高效的javascript事件的技术
    想做web开发 就学JavaScript
    git的简单理解及基础操作命令
    《CSS权威指南》基础复习+查漏补缺
    TypeScript Writing .d.ts files(编写声明文件)
  • 原文地址:https://www.cnblogs.com/AOQNRMGYXLMV/p/4394173.html
Copyright © 2011-2022 走看看