zoukankan      html  css  js  c++  java
  • 【uva11468-Substring】AC自动机+dp

    http://acm.hust.edu.cn/vjudge/problem/31655

    题意:给定k个模板串,n个字符以及选择它的概率pro[i],要构造一个长度问L的字符串s,问s不包含任意一个模板串的概率。

    题解:

    ed[i]标记trie上的点i是不是任意一个模板串的结尾(在求fail的时候ed[i]|=ed[i.fail])
    d[i][l]表示从i出发还要走l步,构造的串不含模板串的概率,dp一下。注意清零。

      1 #include<cstdio>
      2 #include<cstdlib>
      3 #include<cstring>
      4 #include<iostream>
      5 #include<queue>
      6 using namespace std;
      7 
      8 const int N=30,L=110,S=66;
      9 char s[L];
     10 int cnt[N*L];
     11 double d[N*L][L],pro[70];
     12 bool ed[N*L];
     13 queue<int> q;
     14 int num,k,n,l;
     15 struct node{
     16     int son[70];
     17     int fail;
     18 }a[N*L];
     19 
     20 int idx(char c)
     21 {
     22     if(c<='z' && c>='a') return c-'a'+1;
     23     if(c<='Z' && c>='A') return c-'A'+27;
     24     return c-'0'+53;
     25 }
     26 
     27 void clear(int x)
     28 {
     29     a[x].fail=0;
     30     memset(a[x].son,0,sizeof(a[x].son));
     31 }
     32 
     33 void trie(char *c)
     34 {
     35     int l=strlen(c);
     36     int x=0;
     37     for(int i=0;i<l;i++)
     38     {
     39         int t=idx(c[i]);
     40         if(!a[x].son[t])
     41         {
     42             num++;
     43             clear(num);
     44             a[x].son[t]=num;
     45         }
     46         x=a[x].son[t];
     47     }
     48     ed[x]=1;
     49 }
     50 
     51 void buildAC()
     52 {
     53     while(!q.empty()) q.pop();
     54     for(int i=1;i<=S;i++)
     55         if(a[0].son[i]) q.push(a[0].son[i]);
     56     while(!q.empty())
     57     {
     58         int x=q.front();q.pop();
     59         int fail=a[x].fail;
     60         for(int i=1;i<=S;i++)
     61         {
     62             int y=a[x].son[i];
     63             if(y)
     64             {
     65                 a[y].fail=a[fail].son[i];
     66                 ed[y]|=ed[a[fail].son[i]];
     67                 q.push(y);
     68             }
     69             else a[x].son[i]=a[fail].son[i];
     70         }
     71     }
     72 }
     73 
     74 double count(int x,int l)
     75 {
     76     if(l==0) return d[x][l]=1.0;
     77     if(d[x][l]!=-1) return d[x][l];
     78     d[x][l]=0;
     79     for(int i=1;i<=S;i++)
     80     {
     81         if(!pro[i]) continue;
     82         int y=a[x].son[i];
     83         if(!ed[y]) d[x][l]+=pro[i]*count(y,l-1);
     84     }
     85     return d[x][l];
     86 }
     87 
     88 int main()
     89 {
     90     freopen("a.in","r",stdin);
     91     freopen("a.out","w",stdout);
     92     int T,cas=0;
     93     scanf("%d",&T);
     94     while(T--)
     95     {
     96         num=0;
     97         clear(0);
     98         memset(cnt,0,sizeof(cnt));
     99         memset(ed,0,sizeof(ed));
    100         memset(pro,0,sizeof(pro));
    101         scanf("%d",&k);
    102         for(int i=1;i<=k;i++)
    103         {
    104             scanf("%s",s);
    105             trie(s);
    106         }
    107         buildAC();
    108         scanf("%d",&n);getchar();
    109         for(int i=1;i<=n;i++)
    110         {
    111             char c;
    112             scanf("%c",&c);getchar();
    113             scanf("%lf",&pro[idx(c)]);getchar();
    114         }
    115         scanf("%d",&l);
    116         for(int i=0;i<=num;i++)
    117             for(int j=0;j<=l;j++)
    118                 d[i][j]=-1;
    119         printf("Case #%d: %lf
    ",++cas,count(0,l));
    120     }
    121     return 0;
    122 }
  • 相关阅读:
    Clojure新手入门
    背包问题——第一篇
    矩阵快速幂的最简单用法
    加密的病历单
    JAVA NIO学习四:Path&Paths&Files 学习
    JAVA NIO学习三:NIO 的非阻塞式网络通信
    JAVA NIO学习二:通道(Channel)与缓冲区(Buffer)
    JAVA NIO学习一:NIO简介、NIO&IO的主要区别
    JAVA IO分析三:IO总结&文件分割与合并实例
    JAVA IO分析二:字节数组流、基本数据&对象类型的数据流、打印流
  • 原文地址:https://www.cnblogs.com/KonjakJuruo/p/5686437.html
Copyright © 2011-2022 走看看