zoukankan      html  css  js  c++  java
  • uva 11468 Substring

    题意:给你 k 个模板串,然后给你一些字符的出现概率,然后给你一个长度 l ,问你这些字符组成的长度为 l 的字符串不包含任何一个模板串的概率。

    思路:AC自动机+概论DP

    首先用K个模板构造好AC自动机。题目上说长L的新串的子串不包含任何一个K串,其实就是说在构造好的树中,从根往下走L步都不包含K个模板。此题用match标记是否为K模板串。

    状态转移方程代码中注释了。

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<queue>
      4 #include<cstdio>
      5 #include<map>
      6 #include<string>
      7 using namespace std;
      8 
      9 const int SIGMA_SIZE = 64;
     10 const int MAXNODE = 500; // 结点总数
     11 const int MAXS = 20 + 10; // 模板个数
     12 
     13 int idx[256], n;
     14 double prob[SIGMA_SIZE];
     15 
     16 struct AhoCorasickAutomata
     17 {
     18     int ch[MAXNODE][SIGMA_SIZE];
     19     int f[MAXNODE];    // fail函数
     20     int match[MAXNODE];  // 是否包含某一个字符串
     21     int sz;            // 结点总数
     22 
     23     void init()
     24     {
     25         sz = 1;
     26         memset(ch[0], 0, sizeof(ch[0]));
     27     }
     28 
     29     // 插入字符串
     30     void insert(char *s)
     31     {
     32         int u = 0, n = strlen(s);
     33         for(int i = 0; i < n; i++)
     34         {
     35             int c = idx[s[i]];
     36             if(!ch[u][c])
     37             {
     38                 memset(ch[sz], 0, sizeof(ch[sz]));
     39                 match[sz] = 0;
     40                 ch[u][c] = sz++;
     41             }
     42             u = ch[u][c];
     43         }
     44         match[u] = 1;
     45     }
     46 
     47     // 计算fail函数
     48     void getFail()
     49     {
     50         queue<int> q;
     51         f[0] = 0;
     52         // 初始化队列
     53         for(int c = 0; c < SIGMA_SIZE; c++)
     54         {
     55             int u = ch[0][c];
     56             if(u)
     57             {
     58                 f[u] = 0;
     59                 q.push(u);
     60             }
     61         }
     62         // 按BFS顺序计算fail
     63         while(!q.empty())
     64         {
     65             int r = q.front();
     66             q.pop();
     67             for(int c = 0; c < SIGMA_SIZE; c++)
     68             {
     69                 int u = ch[r][c];
     70                 if(!u)
     71                 {
     72                     ch[r][c] = ch[f[r]][c];
     73                     continue;
     74                 }
     75                 q.push(u);
     76                 int v = f[r];
     77                 while(v && !ch[v][c]) v = f[v];
     78                 f[u] = ch[v][c];
     79                 match[u] |= match[f[u]];
     80             }
     81         }
     82     }
     83 };
     84 
     85 AhoCorasickAutomata ac;
     86 
     87 double d[MAXNODE][105];
     88 int vis[MAXNODE][105];
     89 
     90 double getProb(int u, int L)//d[u][L]=prob[u]*d[v][L-1]状态转方程 v为u的儿子可以走节点
     91 {
     92     if(!L) return 1.0;
     93     if(vis[u][L])
     94         return d[u][L];
     95     vis[u][L] = 1;
     96     d[u][L]=0.0;
     97     for(int i = 0; i < n; i++)
     98         if(!ac.match[ac.ch[u][i]])
     99             d[u][L] += prob[i] * getProb(ac.ch[u][i], L-1);
    100     return d[u][L];
    101 }
    102 
    103 char s[30][30];
    104 
    105 int main()
    106 {
    107     int T;
    108     scanf("%d", &T);
    109     for(int kase = 1; kase <= T; kase++)
    110     {
    111         int k, L;
    112         scanf("%d", &k);
    113         for(int i = 0; i < k; i++) scanf("%s", s[i]);
    114         scanf("%d", &n);
    115         for(int i = 0; i < n; i++)
    116         {
    117             char ch[9];
    118             scanf("%s%lf", ch, &prob[i]);
    119             idx[ch[0]] = i;
    120         }
    121         ac.init();
    122         for(int i = 0; i < k; i++) ac.insert(s[i]);
    123         ac.getFail();
    124         scanf("%d", &L);
    125         memset(vis, 0, sizeof(vis));
    126         memset(d,0,sizeof(d));
    127         printf("Case #%d: %.6lf
    ", kase, getProb(0, L));
    128     }
    129     return 0;
    130 }
    View Code
  • 相关阅读:
    POJ2104&&HDU2665(静态区间第K小)
    HDU4763
    js 获取视频的第一帧
    hadoop 集群配置
    redis_cli 批量删除
    vmware centos 7 更新vmware-tools
    php计算两个整数的最大公约数常用算法小结
    centOS 7 配置NAT模式
    centOS配置NAT模式
    show table status 获取表的信息
  • 原文地址:https://www.cnblogs.com/ITUPC/p/5024457.html
Copyright © 2011-2022 走看看