zoukankan      html  css  js  c++  java
  • UVA 11468 Substring (记忆化搜索 + AC自动鸡)

    传送门

    题意: 给你K个模式串, 然后,再给你 n 个字符, 和它们出现的概率 p[ i ], 模式串肯定由给定的字符组成。

       且所有字符,要么是数字,要么是大小写字母。 问你生成一个长度为L的串,不包含任何模式串的概率是多少。

    解: 记忆化搜索 +  AC自动机。 对模式串建一个AC自动机, 不需要last[ ] 和 val[ ], 只需要一个 metch[ ]。

       维护一下这个点是否是某个模式串的最后一个字符节点,若是,则这个点不能走。

       然后, 剩下的就是从根节点,随便走 L 步, 记得要记忆化, 否则超时。

       记得数组开足够大, 否则 wa 一下午。

       

    #include <bits/stdc++.h>
    #define LL long long
    #define rep(i, j, k) for(int i = j; i <= k; i++)
    #define dep(i, j, k) for(int i = k; i >= j; i--)
    #define INF 0x3f3f3f3f
    #define inf 0x3f3f3f3f3f3f3f3f
    #define mem(i, j) memset(i, j, sizeof(i))
    #define pb push_back
    using namespace std;
    
    const int N = 20 * 20 + 5, M = 105;
    char op[2];
    double tmp;
    struct Trie {
        int a[N][M], tot, metch[N], Fail[N], vis[N][M], n;
        double p[N], dp[N][M];
        char ch[M];
        void init() {
            mem(a[0], 0); tot = 1; metch[0] = 0; mem(dp, 0); mem(p, 0); mem(vis, 0);
        }
        int get(char Q) {
            if(Q >= '0' && Q <= '9') return Q - '0' + 1;
            if(Q >= 'A' && Q <= 'Z') return Q - 'A' + 11;
            return Q - 'a' + 37;
        }
        void join(char s[]) {
            int now = 0; int len = strlen(s);
            rep(i, 0, len - 1) {
                int id = get(s[i]);
                if(!a[now][id]) {
                    mem(a[tot], 0); metch[tot] = 0;
                    a[now][id] = tot++;
                }
                now = a[now][id];
            }
            metch[now] = 1;
        }
        void getFail() {
            queue<int> Q; while(!Q.empty()) Q.pop();
            rep(i, 1, M - 1) {
                if(a[0][i]) {
                    Q.push(a[0][i]); Fail[a[0][i]] = 0;
                }
            }
            while(!Q.empty()) {
                int now = Q.front(); Q.pop();
                rep(i, 1, M - 1) {
                    int u = a[now][i];
                    if(u == 0) a[now][i] = a[Fail[now]][i];
                    else {
                        Q.push(u);
                        Fail[u] = a[Fail[now]][i];
                        metch[u] |= metch[Fail[u]];
                    }
                }
            }
        }
        double dfs(int now, int L) {
            if(!L) return 1.0;
            if(vis[now][L]) return dp[now][L];
            vis[now][L] = 1;
            double &ans = dp[now][L];
            ans = 0.0;
            rep(i, 1, M - 1) { /// 枚举所有可能字符
                if(!metch[a[now][i]]) { /// 这个节点可以走
                    ans += p[i] * dfs(a[now][i], L - 1);
                }
            }
            return ans;
        }
        void scan() {
            scanf("%d", &n);
            rep(i, 1, n) {
                scanf("%s %lf", op, &tmp);
                int id = get(op[0]);
                p[id] = tmp;
            }
        }
        void print(int cas) {
            int L; scanf("%d", &L);
            printf("Case #%d: ", cas);
            printf("%.6f
    ", dfs(0, L));
        }
    };
    Trie AC;
    char b[25];
    int main() {
        int _; scanf("%d", &_); int cas = 0;
        while(_--) {
            AC.init();
            int k; scanf("%d", &k);
            rep(i, 1, k) {
                scanf("%s", b); AC.join(b);
            }
            AC.getFail();
            AC.scan();
            AC.print(++cas);
        }
        return 0;
    }
    View Code
    一步一步,永不停息
  • 相关阅读:
    jsp>EL表达式语言 小强斋
    jsp>JSP + Servlet + JavaBean开发模式 小强斋
    jsp>Smartupload例子代码 小强斋
    jsp>servlet 小强斋
    jsp>JSP + Servlet + JavaBean开发模式 小强斋
    五言诗
    夜深灯下行
    2011 年数据库大会的PPT下载
    去除iPhone icon的光晕效果
    望苍天
  • 原文地址:https://www.cnblogs.com/Willems/p/12003847.html
Copyright © 2011-2022 走看看