zoukankan      html  css  js  c++  java
  • hdu 5995 Guessing the Dice Roll(AC自动机+矩阵)

    题目链接:hdu 5995 Guessing the Dice Roll

    题意:

    有一个6面的骰子,有n(n10)个人每个人猜了一个长度为l(l10)的序列,不停的掷骰子直到满足一个人的序列则那个人获胜,求每个人获胜的概率。

    题解:

    将他们猜的串插入AC自动机,然后转移k次,这里k要足够大才能收敛,然后因为总节点数最多才60个,所以用矩阵来加速。

    正解应该是用高斯消元来做这个事情。

     1 #include<bits/stdc++.h>
     2 #define mst(a,b) memset(a,b,sizeof(a))
     3 #define F(i,a,b) for(int i=(a);i<=(b);++i)
     4 using namespace std;
     5 
     6 const int AC_N=100,tyn=6;
     7 int s[20],t,n,l,now,all;
     8 double ans[20];
     9 const int mat_N=105;
    10 
    11 struct mat{
    12     double c[mat_N][mat_N];
    13     void init(){mst(c,0);}
    14     mat operator*(mat b){
    15         mat M;int N=all;M.init();
    16         F(i,0,N)F(j,0,N)if(c[i][j]!=0)F(k,0,N)M.c[i][k]+=c[i][j]*b.c[j][k];
    17         return M;
    18     }
    19     mat operator^(int k){
    20         mat ans,M=(*this);int N=all;ans.init();
    21         F(i,0,N)ans.c[i][i]=1;
    22         while(k){if(k&1)ans=ans*M;k>>=1,M=M*M;}
    23         return ans;
    24     }
    25 }A; 
    26  
    27 struct AC_automation{
    28     int tr[AC_N][tyn],cnt[AC_N],Q[AC_N],fail[AC_N],tot;
    29     inline int getid(int x){return x-1;}
    30     void nw(){cnt[++tot]=0,fail[tot]=0;memset(tr[tot],0,sizeof(tr[tot]));}
    31     void init(){tot=-1,fail[0]=-1,nw();}
    32     void insert(int *s,int len,int idx,int x=0){
    33         for(int i=0,w;i<len;x=tr[x][w],i++)
    34             if(!tr[x][w=getid(s[i])])nw(),tr[x][w]=tot;
    35         cnt[x]=idx;
    36     }
    37     void build(int head=1,int tail=0){
    38         for(int i=0;i<tyn;i++)if(tr[0][i])Q[++tail]=tr[0][i];
    39         while(head<=tail)for(int x=Q[head++],i=0;i<tyn;i++)
    40             if(tr[x][i])
    41             {
    42                 fail[tr[x][i]]=tr[fail[x]][i],Q[++tail]=tr[x][i];
    43                 cnt[tr[x][i]]+=cnt[tr[fail[x]][i]];
    44             }
    45             else tr[x][i]=tr[fail[x]][i];
    46     }
    47     void solve()
    48     {
    49         A.init(),all=tot;
    50         F(j,0,tot)
    51         {
    52             if(cnt[j])A.c[j][j]=1;
    53             else F(k,0,5)A.c[tr[j][k]][j]+=1.0/6;
    54         }
    55         A=A^(1<<30);
    56         F(i,0,tot)if(cnt[i])ans[cnt[i]]=A.c[i][0];
    57         F(i,1,n)printf("%.6f%c",ans[i]," 
    "[i==n]);
    58     }
    59     
    60 }AC;
    61 
    62 int main(){
    63     scanf("%d",&t);
    64     while(t--)
    65     {
    66         scanf("%d%d",&n,&l);
    67         AC.init();
    68         F(i,1,n)
    69         {
    70             F(j,0,l-1)scanf("%d",s+j);
    71             AC.insert(s,l,i);
    72         }
    73         AC.build(),AC.solve();
    74     }
    75     return 0;
    76 }
    View Code

     高斯消元版:

     1 #include<bits/stdc++.h>
     2 #define mst(a,b) memset(a,b,sizeof(a))
     3 #define F(i,a,b) for(int i=(a);i<=(b);++i)
     4 using namespace std;
     5 const int AC_N=100,tyn=6;
     6 int s[20],t,n,l,now,all;
     7 
     8 #define eps 1e-9
     9 const int MAXN=220;
    10 double a[MAXN][MAXN],x[MAXN],ans[MAXN];
    11 int equ,var;
    12 
    13 int Gauss()
    14 {
    15     int i,j,k,col,max_r;
    16     for(k=0,col=0;k<equ&&col<var;k++,col++)
    17     {
    18         max_r=k;
    19         for(i=k+1;i<equ;i++)
    20             if(fabs(a[i][col])>fabs(a[max_r][col]))
    21                 max_r=i;
    22         if(fabs(a[max_r][col])<eps)return 0;
    23         if(k!=max_r)
    24         {
    25             for(j=col;j<var;j++)
    26               swap(a[k][j],a[max_r][j]);
    27             swap(x[k],x[max_r]);
    28         }
    29         x[k]/=a[k][col];
    30         for(j=col+1;j<var;j++)a[k][j]/=a[k][col];
    31         a[k][col]=1;
    32         for(i=0;i<equ;i++)if(i!=k)
    33         {
    34             x[i]-=x[k]*a[i][k];
    35             for(j=col+1;j<var;j++)a[i][j]-=a[k][j]*a[i][col];
    36             a[i][col]=0;
    37         }
    38     }
    39     return 1;
    40 }
    41 
    42 struct AC_automation{
    43     int tr[AC_N][tyn],cnt[AC_N],Q[AC_N],fail[AC_N],tot;
    44     inline int getid(int x){return x-1;}
    45     void nw(){cnt[++tot]=0,fail[tot]=0;memset(tr[tot],0,sizeof(tr[tot]));}
    46     void init(){tot=-1,fail[0]=-1,nw();}
    47     void insert(int *s,int len,int idx,int x=0){
    48         for(int i=0,w;i<len;x=tr[x][w],i++)
    49             if(!tr[x][w=getid(s[i])])nw(),tr[x][w]=tot;
    50         cnt[x]=idx;
    51     }
    52     void build(int head=1,int tail=0){
    53         for(int i=0;i<tyn;i++)if(tr[0][i])Q[++tail]=tr[0][i];
    54         while(head<=tail)for(int x=Q[head++],i=0;i<tyn;i++)
    55             if(tr[x][i])
    56             {
    57                 fail[tr[x][i]]=tr[fail[x]][i],Q[++tail]=tr[x][i];
    58                 cnt[tr[x][i]]+=cnt[tr[fail[x]][i]];
    59             }
    60             else tr[x][i]=tr[fail[x]][i];
    61     }
    62     void solve()
    63     {
    64         mst(a,0),mst(x,0),equ=var=tot+1;
    65         
    66         F(j,0,tot)
    67         {
    68             a[j][j]=-1,x[j]=0;
    69             if(!cnt[j])F(k,0,5)a[tr[j][k]][j]+=1.0/6;
    70         }
    71         x[0]=-1;
    72         Gauss();
    73         F(i,0,tot)if(cnt[i])ans[cnt[i]]=x[i];
    74         F(i,1,n)printf("%.6f%c",ans[i]," 
    "[i==n]);
    75     }
    76     
    77 }AC;
    78 
    79 int main(){
    80     scanf("%d",&t);
    81     while(t--)
    82     {
    83         scanf("%d%d",&n,&l);
    84         AC.init();
    85         F(i,1,n)
    86         {
    87             F(j,0,l-1)scanf("%d",s+j);
    88             AC.insert(s,l,i);
    89         }
    90         AC.build(),AC.solve();
    91     }
    92     return 0;
    93 }
    View Code
  • 相关阅读:
    第二次冲刺(7)
    第二次冲刺(6)
    第二次冲刺(5)
    【整理】C#文件操作大全(SamWang)<转>
    c# 文件及目录操作类
    BIOS设置之UEFI/Legacy BIOS切换图文详解
    UEFI+GPT引导实践篇(二):UEFI引导安装64位Win7/Win8
    UEFI+GPT引导实践篇(一):切换到UEFI启动,准备安装介质
    UEFI+GPT引导基础篇(一):什么是GPT,什么是UEFI?
    预装WIN8系统的电脑安装WIN7的方法
  • 原文地址:https://www.cnblogs.com/bin-gege/p/7256011.html
Copyright © 2011-2022 走看看