uva 11468 ac自动机+dp

来源:互联网 发布:net域名后缀排名高吗 编辑:程序博客网 时间:2024/04/27 13:11

题意:

求最后构成的长度为L的字符串不含有模式串的概率,没一个字符的概率已经给出来了。

思路:

    自动机构造转移,然后dp[i][j]表示现在是第i步,在j这个状态。    转移方程就很好写了。

code:

#include <iostream>#include <queue>#include <cstring>#include <cstdio>#include <algorithm>using namespace std;int n;double m[1000];double dp[110][5110];int Next[5010][63],fail[5010],End[5010];struct Trie{    int root,L;    int idx(char x){        if(x<='z' && x>='a') return x-'a';        if(x<='Z' && x>='A') return x-'A'+26;        if(x<='9' && x>='0') return x-'0'+52;    }    int newnode()    {        for(int i = 0;i < 62;i++)            Next[L][i] = -1;        End[L++] = 0;        return L-1;    }    void init()    {        L = 0;        root = newnode();    }    void insert(char buf[])    {        int len = strlen(buf);        int now = root;        for(int i = 0;i < len;i++)        {            if(Next[now][idx(buf[i])] == -1)                Next[now][idx(buf[i])] = newnode();            now = Next[now][idx(buf[i])];        }        End[now] = 1;    }    void build()    {        queue<int>Q;        fail[root] = root;        for(int i = 0;i < 62;i++)            if(Next[root][i] == -1)                Next[root][i] = root;            else            {                fail[Next[root][i]] = root;                Q.push(Next[root][i]);            }        while( !Q.empty() )        {            int now = Q.front();            Q.pop();            End[now] |= End[fail[now]];            for(int i = 0;i < 62;i++)                if(Next[now][i] == -1)                    Next[now][i] = Next[fail[now]][i];                else                {                    fail[Next[now][i]]=Next[fail[now]][i];                    Q.push(Next[now][i]);                }        }    }    void query(){        memset(dp, 0, sizeof(dp));        dp[0][root] = 1;        for(int i=0; i<=n; i++){            for(int j=0; j<L; j++){                for(int k=0; k<62; k++)                    if(End[Next[j][k]] == 0)                         dp[i+1][Next[j][k]] += dp[i][j]*m[k];            }        }    }};char tmp[40];int T;int main(){    Trie t;    cin>>T;    int icase = 0;    while(T--){        memset(m, 0, sizeof(m));        int k;        cin>>k;        t.init();        for(int i=1; i<=k; i++){            scanf("%s", tmp);            t.insert(tmp);         }        t.build();        cin>>n;        double tt;        for(int i=1; i<=n; i++){            scanf("%s %lf", tmp, &tt);                m[t.idx(tmp[0])] = tt;        }        cin>>n;        t.query();        double res = 0;        for(int i=0; i<t.L; i++)            res += dp[n][i];        printf("Case #%d: %.6f\n", ++icase, res);    }    return 0;}
0 0
原创粉丝点击