zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    Java 在方法和作用域内的内部类
    java 内部类和向上转型
    java 内部类使用 .this 和 .new
    java innerclasses(内部类)
    Java过滤器与SpringMVC拦截器之间的关系与区别
    Maven异常:Could not find artifact
    soapUI测试webservice(参数为xml格式的处理方式)
    maven仓库加载本地包依赖
    spring data jpa的学习总结
    Java 中常用缓存Cache机制的实现
  • 原文地址:https://www.cnblogs.com/Sunnie69/p/5550627.html
Copyright © 2011-2022 走看看