• UVA11468 Substring


    题目大意:给你一些模板串和组成这些模板串的字符,从中随机选L个字符,每个字符都有各自被选的概率p,保证p之和为1,问抽到的串不包含模板串的概率

    建一颗tire树,不能走打了tag的标记,走每条边概率已知,求走到深度L的概率,dp[i][j]表示到第i个点还能走j步的概率,转移即可

    但这样做存在问题,可能某个短串是长串的子串,但是上述做法无法判断

    可以建一颗tire树,从某个节点不断走fail,要求fail路径上的点都没有tag标记

    其实这就是last的功能,即最近一个t串相同的ag标记的位置

    莫名其妙空间开大了过不了,开小了过了,没有memset  p数组过不了,memset了过了,是不是数据出的有问题,串中含有给的字符里没有的字符?

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <cstdlib>
      5 #include <algorithm>
      6 #include <queue>
      7 #include <vector>
      8 #include <cmath> 
      9 #define min(a, b) ((a) < (b) ? (a) : (b))
     10 #define max(a, b) ((a) > (b) ? (a) : (b))
     11 #define abs(a) ((a) < 0 ? (-1 * (a)) : (a))
     12 inline void swap(int &a, int &b)
     13 {
     14     long long tmp = a;a = b;b = tmp;
     15 }
     16 inline void read(int &x)
     17 {
     18     x = 0;char ch = getchar(), c = ch;
     19     while(ch < '0' || ch > '9') c = ch, ch = getchar();
     20     while(ch <= '9' && ch >= '0') x = x * 10 + ch - '0', ch = getchar();
     21     if(c == '-') x = -x;
     22 }
     23 
     24 const int INF = 0x3f3f3f3f;
     25 
     26 int t, k, n, l, ch[2000][80], fail[2000], last[2000], cnt, tag[2000], ca, vis[2000][100];
     27 double p[800], dp[2000][100];
     28 char s[200][200], base[800];
     29 int check(char c)
     30 {
     31     if(c >= '0' && c <= '9') return  c - '0' + 1;
     32     if(c >= 'A' && c <= 'Z') return c - 'A' + 11;
     33     return c - 'a' + 37;
     34 }
     35 void insert(int x)
     36 {
     37     int now = 0;
     38     for(register int i = 1;s[x][i] != '';++ i)
     39     {
     40         int tmp = check(s[x][i]);
     41         if(ch[now][tmp]) now = ch[now][tmp];
     42         else now = ch[now][tmp] = ++ cnt;
     43     }
     44     ++ tag[now];
     45 }
     46 
     47 int q[1000], he, ta;
     48 
     49 void build()
     50 {
     51     he = ta = 0;
     52     for(register int i = 1;i <= 62;++ i)
     53         if(ch[0][i]) q[ta ++] = ch[0][i], fail[ch[0][i]] = last[ch[0][i]] = 0;
     54     while(he < ta)
     55     {
     56         int now = q[he ++];
     57         for(register int i = 1;i <= 62;++ i)
     58         {
     59             int u = ch[now][i];
     60             if(!u)
     61             {
     62                 ch[now][i] = ch[fail[now]][i];
     63                 continue;
     64             }
     65             q[ta ++] = u;
     66             int v = fail[now];
     67             while(v && !ch[v][i]) v = fail[v];
     68             fail[u] = ch[v][i];
     69             last[u] = tag[fail[u]] ? fail[u] : last[fail[u]];
     70         }
     71     }
     72 }
     73 
     74 double dfs(int x, int y)
     75 {
     76     if(!y) return 1;
     77     if(vis[x][y]) return dp[x][y];
     78     vis[x][y] = 1;
     79     dp[x][y] = 0;
     80     for(register int i = 1;i <= 62;++ i)
     81         if(!tag[ch[x][i]] && !last[ch[x][i]]) dp[x][y] += p[i] * dfs(ch[x][i], y - 1);
     82     return dp[x][y];
     83 } 
     84 
     85 int main()
     86 {
     87     read(t);
     88     for(ca = 1;t;-- t, ++ ca)
     89     {
     90         memset(ch, 0, sizeof(ch)), memset(tag, 0, sizeof(tag)), cnt = 0, memset(vis, 0, sizeof(vis));memset(p, 0, sizeof(p));
     91         read(k);
     92         for(register int i = 1;i <= k;++ i) scanf("%s", s[i] + 1), insert(i);
     93         read(n);
     94         for(register int i = 1;i <= n;++ i)
     95             scanf("%s", &base[i]), scanf("%lf", &p[check(base[i])]);
     96         read(l);
     97         build();
     98         printf("Case #%d: %.6lf
    ", ca, dfs(0, l));
     99     }
    100     return 0;
    101 }
    UVA11468
  • 相关阅读:
    第六周作业
    2019第四周作业(基础作业+挑战作业)
    第三周作业
    2019第二周基础作业
    求最大值及下标值
    查找整数
    学期总结
    打印沙漏
    币值转换
    远程连接centos7的mysql5.7+ 更改iptables方法
  • 原文地址:https://www.cnblogs.com/huibixiaoxing/p/8323441.html
Copyright © 2020-2023  润新知