HDU 3689 Infinite monkey theorem (uva11468)ac自动机+dp

来源:互联网 发布:js动态添加class属性 编辑:程序博客网 时间:2024/06/05 06:20
ac自动机+dp, 和uva11468 Substring 几乎一样,但访问数组d[1010][30]时,下标写反了,但是结果不对,但是没有报错,表示不解
const int MAX = 30;const int SIGMEA_SIZE = 26;int m, L;//double dp[1010][30];double d[1010][30];bool vis[1010][30];char ca[30];char a[30];double b[30];struct AC{    int ch[MAX][SIGMEA_SIZE];    int val[MAX];    int f[MAX];    int sz;    ///trie;    void init()    {        sz=1;        memset(ch,0,sizeof(ch));        memset(val,0,sizeof(val));///    }///init;    int idx(char c) { return c-'a'; }    void insert(char *s,int v)    {        int u=0,n=strlen(s);        for(int i=0;i<n;i++)        {            int c=idx(s[i]);            if(!ch[u][c])                ch[u][c] = sz++;            u = ch[u][c];        }        val[u] = v;///    }    ///bfs,fail[];    void getFail()    {        queue<int> q;        f[0] = 0;///        //初始化队列        for(int c = 0; c < SIGMEA_SIZE; c++)        {            int u = ch[0][c];            if(u) { f[u] = 0; q.push(u); }///        }        while(!q.empty())        {            int r = q.front(); q.pop();            for(int c = 0; c < SIGMEA_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]];            }        }    }    ///dp[l, u]表示敲到l的长度,在状态u位置时的概率//    double solve()//    {//        CLR(dp, 0);//        dp[0][0] = 1.0;//        REP(i, L)//        {//            REP(j, sz - 1)///!!!//            {//                if (i >= j)//                {//                    REP(r, m)//                    {//                        int c = idx(a[r]);//                        int v = ch[j][c];//                        dp[i + 1][v] += b[c] * dp[i][j];//                    }//                }//            }//        }//        double ans = 0.0;//        FE(i, 1, L)//            ans += dp[i][sz - 1];//        printf("%.2lf%%\n", ans * 100);//    }    ///dp[l, u]表示从状态u出发,敲l的长度,包含串的概率    ///含的概率,最后 dpf(L, 0)//    double dpf(int l, int u)//    {//        if (l <= 0) return 0.0;//        if (vis[l][u]) return d[l][u];//        vis[l][u] = 1;//        double &ans = d[l][u];//        ans = 0.0;//        REP(i, m)//        {//            int c = idx(a[i]);//            int v = ch[u][c];//            if (val[v]) ans += b[c];//            else ans += b[c] * dpf(l - 1, v);//        }//        return ans;//    }    ///不含的概率,最后1.0 - dpf(L, 0)    double dpf(int l, int u)    {        if (l <= 0) return 1.0;        if (vis[l][u]) return d[l][u];        vis[l][u] = 1;        double &ans = d[l][u];        ans = 0.0;        REP(i, m)        {            int c = idx(a[i]);            int v = ch[u][c];            if (!val[v]) ans += b[c] * dpf(l - 1, v);        }        return ans;    }}ac;int main(){    while (cin >> m >> L && (m || L))    {        ac.init();        REP(i, m)        {            scanf(" %c", &a[i]);            scanf("%lf", &b[a[i] - 'a']);        }        RS(ca);        ac.insert(ca, 1);        ac.getFail();        CLR(vis, 0);//        ac.solve();//        printf("%.2lf%%\n", (ac.dpf(L, 0)) * 100);        printf("%.2lf%%\n", (1.0 - ac.dpf(L, 0)) * 100);    }}

原创粉丝点击