zoukankan      html  css  js  c++  java
  • AC自动机+全概率+记忆化DP UVA 11468 Substring

    题目传送门

    题意:训练指南P217

    分析:没有模板串也就是在自动机上走L步,不走到val[u] == v的节点的概率

    PS:边读边insert WA了,有毒啊!

    #include <bits/stdc++.h>
    using namespace std;
    
    const int K = 20 + 5;
    const int L = 100 + 5;
    const int NODE = K * K;
    const int SIZE = 66;
    int idx[256], n;
    struct AC   {
        int ch[NODE][SIZE], fail[NODE], match[NODE], sz;
        void clear(void)    {
            memset (ch[0], 0, sizeof (ch[0]));
            sz = 1;
        }
        void insert(char *P)    {
            int u = 0, lenp = strlen (P);
            for (int c, i=0; i<lenp; ++i)    {
                c = idx[P[i]];
                if (!ch[u][c])  {
                    memset (ch[sz], 0, sizeof (ch[sz]));
                    match[sz] = 0;
                    ch[u][c] = sz++;
                }
                u = ch[u][c];
            }
            match[u] = 1;
        }
        void build(void)    {
            queue<int> que; fail[0] = 0;
            int u;
            for (int c=0; c<SIZE; ++c)  {
                u = ch[0][c];
                if (u)  {
                    fail[u] = 0;    que.push (u);
                }
            }
            while (!que.empty ())   {
                int r = que.front ();   que.pop ();
                for (int c=0; c<SIZE; ++c)  {
                    int u = ch[r][c];
                    if (!u) {
                        ch[r][c] = ch[fail[r]][c]; continue;
                    }
                    que.push (u);
                    int v = fail[r];
                    while (v && !ch[v][c])    v = fail[v];
                    fail[u] = ch[v][c];
                    match[u] |= match[fail[u]];
                }
            }
        }
    }ac;
    
    double prob[SIZE];
    bool vis[NODE][L];
    double dp[NODE][L];
    double DFS(int u, int len)  {
        if (!len)   return 1.0;
        if (vis[u][len])    return dp[u][len];
        vis[u][len] = true;
        double &ret = dp[u][len];
        ret = 0;
        for (int i=0; i<n; ++i) {
            if (!ac.match[ac.ch[u][i]]) ret += prob[i] * DFS (ac.ch[u][i], len - 1);
        }
        return ret;
    }
    char pattern[30][30];
    //char pattern[30];
    
    int main(void)  {
        int T, cas = 0;  scanf ("%d", &T);
        while (T--) {
            //char pattern[30];
            ac.clear ();
            int k;  scanf ("%d", &k);
            for (int i=1; i<=k; ++i)    {
                scanf ("%s", &pattern[i]);
                //scanf ("%s", &pattern);
                //ac.insert (pattern);
            }
            //ac.build ();
            scanf ("%d", &n);
            char str[3];
            for (int i=0; i<n; ++i)    {
                scanf ("%s%lf", &str, &prob[i]);
                idx[str[0]] = i;
            }
            for (int i=1; i<=k; ++i)    ac.insert (pattern[i]);
            ac.build ();
            int len;    scanf ("%d", &len);
            memset (vis, false, sizeof (vis));
            printf ("Case #%d: %.6lf
    ", ++cas, DFS (0, len));
        }
    
        return 0;
    }
    

      

    编译人生,运行世界!
  • 相关阅读:
    WebFrom与MVC异同
    MVC解决WebFrom的缺点
    转载ORM--EF框架
    转载 HashSet用法 合交并差
    用户管理模块数据库设计
    外键的增删改查练习
    索引:如何让主键不自动创建聚集索引???
    SQL-类型转换函数
    SQL-union
    SQL字符串函数
  • 原文地址:https://www.cnblogs.com/Running-Time/p/5123734.html
Copyright © 2011-2022 走看看