hdu 3689 Infinite monkey theorem

去年杭州区域赛的一道题目,比较简单的AC自动机


#include <stdio.h>
#include <string.h>
const int NODE = 1000;
const int CH = 26;
int tree[NODE][CH], cnt;
int fail[NODE], word[NODE], Que[NODE];
int num[128];
char str[20];
double gl[128];
double dp[1010][20];
int mark;
int n, m;
double sum;
int Ins(char *a, int val)
{
    int p = 0;
    for(; *a; a++)
    {
        int c = num[*a];
        if(!tree[p][c])
        {
            memset(tree[cnt], 0, CH * sizeof(int));
            word[cnt] = 0;
            tree[p][c] = cnt++;
        }
        p = tree[p][c];
    }
    word[p] += val;
    return p;
}
void AC()
{
    int *s = Que, *e = Que;
    for(int i = 0; i < CH; i++)
        if(tree[0][i])
        {
            fail[tree[0][i]] = 0;
            *e++ = tree[0][i];
        }
    while(s != e)
    {
        int p = *s++;
        for(int i = 0; i < CH; i++)
        {
            if(tree[p][i])
            {
                int v = tree[p][i];
                *e++ = v;
                fail[v] = tree[fail[p]][i];
            }
            else
            {
                tree[p][i] = tree[fail[p]][i];
            }
        }
    }
}
void solve()
{
    memset(dp, 0, sizeof(dp));
    sum = 0;
    dp[0][0] = 1;

    for(int i = 0; i < m; i++)
    {
        for(int j = 0; j < cnt; j++)
        if(i >= j)
        {
            for(int k = 0; k < CH; k++)
            {
                int v = tree[j][k];
                dp[i + 1][v] += dp[i][j] * gl[k];
            }
        }
        if(dp[i+1][mark] >= 0)
        {
            sum += dp[i+1][mark];
            dp[i+1][mark] = 0;
        }
    }

    /*for(int i = 1; i < m; i++)
    {
        for(int j = 0; j < cnt; j++)
        printf("dp[%d][%d] = %0.4lf   ", i, j, dp[i][j]);
        printf("\n");
    }*/
    printf("%0.2lf%%\n", sum * 100);
}
int main()
{
    for(int i = 0; i < 26; i++)  num[i + 'a'] = i;
    while(scanf("%d%d", &n, &m) != EOF)
    {
        if(n == 0 && m == 0)  break;
        fail[0] = 0;
        cnt = 1;
        memset(tree[0], 0, CH * sizeof(int));
        memset(gl, 0, sizeof(gl));
        for(int i = 1; i <= n; i++)
        {
            double x;
            scanf("%s%lf", str, &x);
            gl[str[0] - 'a'] = x;
        }
        scanf("%s", str);
        mark = Ins(str, 1);
        AC();
        solve();
    }
    return 0;
}


你可能感兴趣的:(hdu 3689 Infinite monkey theorem)