• UVA_11468_Substring_(AC自动机+概率动态规划)


    描述


    https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2463

    给出一些子串.然后给出一些字符,以及每个字符出现的概率.现在用这些字符组成一个长度为s的字符串,问之前给出的子串都没有在这个字符串中出现的概率是多少.

    分析


    边选字母边匹配.只要前面的字串都不能匹配成功即可.用前面的那些子串造出个AC自动机,然后在上面跑.用match数组表示每个点是否是单词节点,根据题意,只要不是单词节点都可以跑.然后AC自动机在get_fail的时候把没有的边补上.

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 const int maxt=50+5,maxk=20+5,maxl=100+5,maxnode=20*20+5,type=26+26+10;
     5 int t,k,l,n,kase;
     6 char p[maxk][20];
     7 double pro[type];
     8 inline int idx(char c){
     9     if(c>='0'&&c<='9') return c-'0';
    10     if(c>='a'&&c<='z') return c-'a'+10;
    11     return c-'A'+36;
    12 }
    13 struct Aho_Corasick{
    14     int ch[maxnode][type];
    15     int f[maxnode];
    16     double dp[maxnode][maxl];
    17     bool match[maxnode];
    18     int sz;
    19     void init(){
    20         sz=1;
    21         match[0]=false;
    22         memset(pro,0,sizeof pro);
    23         memset(ch[0],0,sizeof ch[0]);
    24         memset(dp,-1,sizeof dp);
    25     }
    26     void insert(char *s){
    27         int u=0;
    28         for(;*s;s++){
    29             int c=idx(*s);
    30             if(!ch[u][c]){
    31                 memset(ch[++sz],0,sizeof ch[sz]);
    32                 match[sz]=false;
    33                 ch[u][c]=sz;
    34             }
    35             u=ch[u][c];
    36         }
    37         match[u]=true;
    38     }
    39     void get_fail(){
    40         queue <int> q;
    41         f[0]=0;
    42         for(int c=0;c<type;c++){
    43             int u=ch[0][c];
    44             if(u){ f[u]=0; q.push(u); }
    45         }
    46         while(!q.empty()){
    47             int r=q.front(); q.pop();
    48             for(int c=0;c<type;c++){
    49                 int u=ch[r][c];
    50                 if(!u){ ch[r][c]=ch[f[r]][c]; continue; }
    51                 q.push(u);
    52                 int v=f[r];
    53                 f[u]=ch[v][c];
    54                 match[u]|=match[f[u]];
    55             }
    56         }
    57     }
    58     double get_pro(int u,int l){
    59         if(!l) return 1.0;
    60         if(dp[u][l]>=0) return dp[u][l];
    61         double &ans=dp[u][l];
    62         ans=0.0;
    63         for(int c=0;c<type;c++)if(!match[ch[u][c]]) ans+=pro[c]*get_pro(ch[u][c],l-1);
    64         return ans;
    65     }
    66 }ac;
    67 int main(){
    68     scanf("%d",&t);
    69     while(t--){
    70         ac.init();
    71         scanf("%d",&k);
    72         for(int i=1;i<=k;i++){
    73             scanf("%s",p[i]);
    74             ac.insert(p[i]);
    75         }
    76         ac.get_fail();
    77         scanf("%d",&n);
    78         for(int i=1;i<=n;i++){
    79             char c;
    80             while(c=getchar(),c=='
    ');
    81             scanf("%lf",&pro[idx(c)]);
    82         }
    83         scanf("%d",&l);
    84         printf("Case #%d: %lf
    ",++kase,ac.get_pro(0,l));
    85     }
    86     return 0;
    87 }
    View Code

    11468
    Substring
    Given a set of pattern strings, and a text, you have to find, if any of the pattern is a substring of the
    text. If any of the pattern string can be found in text, then print ‘yes’, otherwise ‘no’ (without quotes).
    But, unfortunately, thats not what is asked here.
    The problem described above, requires a input file generator. The generator generates a text of
    length L, by choosing L characters randomly. Probability of choosing each character is given as priori,
    and independent of choosing others.
    Now, given a set of patterns, calculate the probability of a valid program generating “no”.
    Input
    First line contains an integer T , the number of test cases. Each case starts with an integer K, the
    number of pattern strings. Next K lines each contain a pattern string, followed by an integer N ,
    number of valid characters. Next N lines each contain a character and the probability of selecting that
    character, p i . Next an integer L, the length of the string generated. The generated text can consist of
    only the valid characters, given above.
    There will be a blank line after each test case.
    Output
    For each test case, output the number of test case, and the probability of getting a “no”.
    Constraints:
    • T ≤ 50
    • K ≤ 20
    • Length of each pattern string is between 1 and 20
    • Each pattern string consists of only alphanumeric characters (a to z, A to Z, 0 to 9)
    • Valid characters are all alphanumeric characters


    p i = 1
    • L ≤ 100
    Sample Input
    2
    1
    a
    2
    a 0.5
    b 0.5
    2
    2
    ab
    2
    a 0.2
    b 0.8
    2
    Sample Output
    Case #1: 0.250000
    Case #2: 0.840000

  • 相关阅读:
    Win Form 项目中app.config读取和修改 [ZT]
    实现全站统一的Page_PreInit()等事件
    DateTime的所有格式化输出
    大三下的半学期快过去了。。
    SQL Server 中易混淆的数据类型
    解决RD2作业在IE和Fire Fox中CSS效果不同的问题~
    AJAX也广告?
    App_Code目录下的全局类
    怀疑我不是那种材料。。
    用了几天Asp.Net 2.0遇到的几个小问题
  • 原文地址:https://www.cnblogs.com/Sunnie69/p/5550627.html
Copyright © 2020-2023  润新知