hdu 3992 Crazy Typewriter AC自动机+高斯消元求期望

Problem Description
There was a crazy typewriter before. When the writer is not very sober, it would type characters randomly, one per second, the possiblities of characters may differ.
The protagonist in this problem wants to tell acmers some secrets, of course, by the typewriter.

There had been several opportunities, but the protagonist let them sliped. Now, another opportunity came, the writer started a new paragraph. The protagonist found 
that he could set the possiblities of each character in happy astonishment. After the possiblities had been set, he wanted to know the exception of time at least the writer need to be mind-absent if any secret was typed out.

fewovigwnierfbiwfioeifaorfwarobahbgssjqmdowj
 

Input
There are several cases, no more than 15.
The first line of each case contains an integer n, no more than 15, indicating the number of secrets.
The second line contains 26 real numbers, indicating the set possibilities of 'a'-'z', respectively, the sum would be 1.0 .
Then n lines, each contains a secret, no longer than 15, which is made up by lowercase letters 'a'-'z'.
 

Output
A single line contains the expectation of time for each case, in seconds with six decimal, if the exception doesn't exist, output "Infinity"
 

Sample Input
  
  
2 0.5000 0.5000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 ab aa
 

Sample Output
  
  
3.000000

//


#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
const int maxn=100000;
struct Node
{
    int flag;
    int id;
    Node* next[26];
    Node* fail;
};
Node* root;
Node temp[maxn];
int tp;
void reset(Node* p)
{
    p->flag=0;p->id=tp-1;
    for(int i=0;i<26;i++) p->next[i]=NULL;
    p->fail=root;
    if(p==root) p->fail=NULL;
}
void init()
{
    tp=0;
    root=&temp[tp++];
    reset(root);
}
void insert(char* str)
{
    Node* p=root;
    for(int i=0;str[i];i++)
    {
        int x=str[i]-'a';
        if(p->next[x]==NULL)
        {
            p->next[x]=&temp[tp++];
            reset(p->next[x]);
        }
        p=p->next[x];
    }
    p->flag=1;
}
Node* que[maxn];
int front,rear;
void DFA()
{
    front=rear=0;
    que[rear++]=root;
    while(front<rear)
    {
        Node* t=que[front++];
        for(int i=0;i<26;i++)
        {
            Node* cnt=t->next[i];
            if(cnt!=NULL)
            {
                Node* fath=t->fail;
                while(fath!=NULL&&fath->next[i]==NULL)
                {
                    fath=fath->fail;
                }
                if(fath==NULL)
                {
                    cnt->fail=root;
                }
                else cnt->fail=fath->next[i];
                cnt->flag|=cnt->fail->flag;//important
                que[rear++]=cnt;
            }
        }
    }
}
double pet[26];
int n;
char str[maxn];
double a[1000][1000];
int equ,var;//从0开始
void toMatrix()
{
    var=rear;
    equ=0;
    memset(a,0,sizeof(a));
    for(int i=0;i<rear;i++)
    {
        Node* p=&temp[i];
        if(p->flag)
        {
            a[equ][p->id]=1;
            a[equ++][var]=0;
            continue;
        }
        a[equ][p->id]=-1;
        a[equ][var]=-1;
        for(int j=0;j<26;j++)
        {
            Node* cnt=p->next[j];
            int k;
            if(cnt!=NULL)
            {
                k=cnt->id;
                a[equ][k]+=pet[j];
            }
            else
            {
                Node* fath=p->fail;
                while(fath!=NULL&&fath->next[j]==NULL)
                {
                    fath=fath->fail;
                }
                if(fath!=NULL)
                {
                    k=fath->next[j]->id;
                    a[equ][k]+=pet[j];
                }
                else
                {
                    k=0;
                    a[equ][0]+=pet[j];
                }
            }
        }
        equ++;
    }
}
const double eps=1e-10;
double x[1000];
void Gauss()
{
    for(int i=0;i<equ;i++)
    {
        int j;
        for(j=i;j<equ;j++)
        {
            if(fabs(a[j][i])>eps) break;
        }
        for(int k=i;k<=var;k++) swap(a[i][k],a[j][k]);
        for(j=i+1;j<equ;j++)
        {
            double p=-a[j][i]/a[i][i];
            for(int k=i;k<=var;k++) a[j][k]+=a[i][k]*p;
        }
    }
    for(int i=equ-1;i>=0;i--)
    {
        x[i]=a[i][var]/a[i][i];
        a[i][var]/=a[i][i];a[i][i]=1;
        for(int j=i-1;j>=0;j--)
        {
            a[j][var]+=-a[j][i]*a[i][var];
            a[j][i]=0;
        }
    }
}
void debug()
{
    for(int i=0;i<equ;i++)
    {
        for(int j=0;j<=var;j++) cout<<a[i][j]<<"  ";cout<<endl;
    }cout<<"........................"<<endl;
}
int main()
{
    while(scanf("%d",&n)==1)
    {
        init();
        for(int i=0;i<26;i++) scanf("%lf",&pet[i]);
        int flag=0;
        for(int i=0;i<n;i++)
        {
            scanf("%s",str);
            insert(str);
            int f=1;
            for(int j=0;str[j];j++)
            {
                int x=str[j]-'a';
                if(fabs(pet[x])<eps)
                {
                    f=0;break;
                }
            }
            if(f) flag=1;


        }
        if(!flag)
        {
            printf("Infinity\n");
            continue;
        }
        DFA();
        toMatrix();
        //debug();
        Gauss();
        //debug();
        printf("%.6lf\n",x[0]);
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值