zoukankan      html  css  js  c++  java
  • UVA 11468 Substring (AC自动机)

    用把失配边也加到正常边以后AC自动机,状态是长度递减的DAG,每次选一个不会匹配字符的转移。

    dp[u][L]表示当前在tire树上u结点长度还剩L时候不匹配的概率,根据全概率公式跑记忆化搜索。

    #include<bits/stdc++.h>
    using namespace std;
    typedef double ld;
    const int maxnds = 21*21, sigma_size = 62;
    int nds;
    int ch[maxnds][sigma_size];
    double p[sigma_size];
    int f[maxnds];
    int id[256];
    bool val[maxnds];
    int N;
    void getF()
    {
        queue<int> q;
        f[0] = 0;
        for(int c = 0; c < sigma_size; c++){
            int u = ch[0][c];
            if(u) { q.push(u); f[u] = 0; }
        }
        while(q.size()){
            int r = q.front(); q.pop();
            for(int c = 0; c < sigma_size; c++){
                int u = ch[r][c];
                if(!u) {
                    ch[r][c] = ch[f[r]][c]; continue;
                }
                q.push(u);
                int v = f[r];
                while(v && !ch[v][c]) v = f[v];
                f[u] = ch[v][c];
                val[u] |= val[f[u]];
            }
        }
    }
    
    void add(char *s)
    {
        int n = strlen(s), u = 0;
        for(int i = 0; i < n; i++){
            int c = id[s[i]];
            if(!ch[u][c]){
                memset(ch[nds],0,sizeof(ch[nds]));
                val[nds] = false;
                ch[u][c] = nds++;
            }
            u = ch[u][c];
        }
        val[u] = true;
    }
    const int maxL = 101;
    ld dp[maxnds][maxL];
    bool vis[maxnds][maxL];
    bool exist[sigma_size];
    
    ld dfs(int u,int L)
    {
        if(!L) return 1;
        if(vis[u][L]) return dp[u][L];
        vis[u][L] = true;
        ld &ret = dp[u][L];
        ret = 0;
        for(int i = 0; i < sigma_size; i++)if(exist[i]){
            if(!val[ch[u][i]]) ret += p[i]*dfs(ch[u][i],L-1);
        }
        return ret;
    }
    
    int id_cnt;
    
    void init()
    {
        memset(ch[0],0,sizeof(ch[0]));
        nds = 1;
        val[0] = false;
        memset(exist,0,sizeof(exist));
    }
    
    #define cerid ,cout<<id[i]<<endl
    #define cer(x) cout<<x<<endl;
    const int maxn = 25;
    char temp[maxn];
    int main()
    {
        //freopen("in.txt","r",stdin);
        for(int i = '0'; i <= '9'; i++) id[i] = i-'0' ;
        for(int i = 'A'; i <= 'Z'; i++) id[i] = i-'A'+10 ;
        for(int i = 'a'; i <= 'z'; i++) id[i] = i-'a'+36 ;
        int T;cin>>T;
        int kas = 0;
        while(T--){
            init();
            int K; scanf("%d",&K);
            for(int i = 0; i < K; i++){
                scanf("%s",temp);
                add(temp);
            }
            scanf("%d",&N);
            for(int i = 0; i < N; i++){
                scanf("%s",temp);
                scanf("%lf",p+id[*temp]);
                exist[id[*temp]] = true;
            }
            getF();
            int L; scanf("%d",&L);
            memset(vis,0,sizeof(vis));
            printf("Case #%d: %lf
    ",++kas,dfs(0,L));
        }
        return 0;
    }
  • 相关阅读:
    自动装箱和==和equals
    4.1 java 类加载器
    23种设计模式
    ionic2打包 配置路径
    ionic2 native app 更新用户头像暨文件操作
    Spring Security三种认证
    maven设置本地仓库地址和设置国内镜像
    ps选框工具全解
    最长公共子序列问题
    内部排序算法的稳定性
  • 原文地址:https://www.cnblogs.com/jerryRey/p/4798408.html
Copyright © 2011-2022 走看看