码迷,mamicode.com
首页 > 其他好文 > 详细

WHU 1572 Cyy and Fzz(自动机+DP)

时间:2015-04-23 00:04:36      阅读:185      评论:0      收藏:0      [点我收藏+]

标签:

Description
As Cyy and Fzz are both busy repairing the network, Sama feel a little boring because it’s he who select Teemo during that game. Of cause his Teemo will stay alive since he has used the summoner spell Flash to avoid being killed. Since there is no network available, he wants to do something else to pass the time. He writes some strings randomly on the paper to kill the boring time.
A few minutes later he realizes that what he writes on the paper is not truly random, in fact it reflects what he is concerned about. Then he comes up with a question, what is the expect number of interesting strings that will appear in the random string he writes? (The characters Sama writes are all lowercase Latin letters, in this problem we consider the probability that each character appears as the same, that is, 1/26)
Input
The first line is an integer T (T <= 13) indicates the case numbers.
Then followed by T test cases. The first line of each test case contains two integers n and L(n <= 8, L <= 14), the number of interesting strings and the length of the string that Sama writes, then followed by n lines, the interesting strings. We promise that the interesting string is not longer than 12. (Notice that there may exist two or more same strings among the n interesting strings.)
Output
For each test case output one line, the expect number of interesting strings that will appear in the string Sama writes (Accurate to 6 digits after the decimal point).
Sample Input
3
1 1
a
3 4
cyy
fzz
sama
8 14
fatezero
nisekoi
nogamenolife
monthlygirls
nozakikun
datealive
sakura
sora
Sample Output
0.038462
0.000230
0.000024
Hint
自动机+DP:
用可以走的字符串构造自动机,状态压缩dp[i][j][k]:表示长度为i,走到自动机j节点,字符串包含情况为k
概率。求下期望就得出答案了。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<string>
#include<iostream>
#include<queue>
#include<cmath>
#include<map>
#include<stack>
#include<bitset>
using namespace std;
#define REPF( i , a , b ) for ( int i = a ; i <= b ; ++ i )
#define REP( i , n ) for ( int i = 0 ; i < n ; ++ i )
#define CLEAR( a , x ) memset ( a , x , sizeof a )
typedef long long LL;
typedef pair<int,int>pil;
const int INF = 0x3f3f3f3f;
double dp[20][110][(1<<8)+10];
int t,n,l;
struct AC{
    int next[110][26];
    int fail[110],ed[110];
    int root,L;
    int newnode()
    {
        for(int i=0;i<26;i++)
           next[L][i]=-1;
        ed[L++]=0;
        return L-1;
    }
    void init()
    {
        L=0;
        root=newnode();
    }
    void Insert(char buf[],int id)
    {
        int len=strlen(buf);
        int now=root;
        for(int i=0;i<len;i++)
        {
            int x=buf[i]-'a';
            if(next[now][x]==-1)
                next[now][x]=newnode();
            now=next[now][x];
        }
        ed[now]|=(1<<id);
    }
    void Build_AC()
    {
        queue<int>q;
        fail[root]=root;
        for(int i=0;i<26;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();ed[now]|=ed[fail[now]];
            for(int i=0;i<26;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 solve()
    {
        CLEAR(dp,0);
        dp[0][0][0]=1.0;
        for(int i=0;i<l;i++)
        {
            for(int j=0;j<L;j++)
            {
                for(int k=0;k<(1<<n);k++)
                {
                    if(dp[i][j][k]!=0)
                    {
                        for(int h=0;h<26;h++)
                        {
                            int now=next[j][h];
                            dp[i+1][now][ed[now]|k]+=1.0/26*dp[i][j][k];
                        }
                    }
                }
            }
        }
        double ans=0;
        for(int i=0;i<L;i++)
        {
            for(int j=0;j<(1<<n);j++)
            {
                int cnt=0;
                for(int k=0;k<26;k++)
                    if(j&(1<<k)) cnt++;
                ans+=cnt*dp[l][i][j];
            }
        }
        printf("%.6f\n",ans);
    }
};
AC A;
int main()
{
    char str[20];
    scanf("%d",&t);
    while(t--)
    {
        A.init();
        scanf("%d%d",&n,&l);
        REP(i,n)
        {
            scanf("%s",str);
            A.Insert(str,i);
        }
        A.Build_AC();
        A.solve();
    }
    return 0;
}

/*
3
1 1
a
3 4
cyy
fzz
sama
8 14
fatezero
nisekoi
nogamenolife
monthlygirls
nozakikun
datealive
sakura
sora
*/


WHU 1572 Cyy and Fzz(自动机+DP)

标签:

原文地址:http://blog.csdn.net/u013582254/article/details/45203331

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!