zoukankan      html  css  js  c++  java
  • HDU-5955 Guessing the Dice Roll AC自动机+高斯消元

    HDU-5955 Guessing the Dice Roll

    题意

    (n)个人,每个人给出一个长度为(m)的整数序列,序列中每个数为(1 sim 6)中的一个,用一颗骰子不停的掷,直到骰子掷出的数组成的序列的一个后缀能匹配上某个人的猜测序列,游戏结束,那个人获胜,问每个人获胜的概率。

    (n,mle 10)

    分析

    把每个序列扔进AC自动机建fail树,因为初始状态对应的为空串,所以自动机初始状态的概率设为(1),然后设(a_1,a_2,dots,a_k)为可以转移到结点(i)的非终止结点,(x_i)为结点(i)的概率,那么有

    [x_i= frac{1}{6}x_{a_1}+frac{1}{6}x_{a_2}+ dots + frac{1}{6} x_{a_k} ]

    移项一下得

    [-x_i+frac{1}{6}x_{a_1}+frac{1}{6}x_{a_2}+ dots + frac{1}{6} x_{a_k}=0 ]

    可以对自动机上每个结点都列一个方程,得到一个(n)元一次方程组,利用高斯消元解方程即可。

    Code

    #include<bits/stdc++.h>
    #define rep(i,x,n) for(int i=x;i<=n;i++)
    #define per(i,n,x) for(int i=n;i>=x;i--)
    #define sz(a) int(a.size())
    #define rson mid+1,r,p<<1|1
    #define pii pair<int,int>
    #define lson l,mid,p<<1
    #define ll long long
    #define pb push_back
    #define mp make_pair
    #define se second
    #define fi first
    using namespace std;
    const double eps=1e-8;
    const int mod=1e9+7;
    const int N=1e2+10;
    const int inf=1e9;
    int T,n,m,a[11],b[11];
    double A[110][110],ans[110];
    struct ACtree{
        int son[N][7],fail[N],ed[N],tot;
        int newnode(){
            for(int i=1;i<=6;i++) son[tot][i]=0;
            ed[tot++]=0;
            return tot-1;
        }
        void init(){
            tot=0;
            newnode();
        }
        void ins(int x){
            int rt=0;
            for(int i=0;i<m;i++){
                if(!son[rt][a[i]]) son[rt][a[i]]=newnode();
                rt=son[rt][a[i]];
            }
            ed[rt]=1;
            b[x]=rt;
        }
        void gauss(int n){
            for(int i=1;i<n;i++){
                if(A[i][i]==0){
                    int id=0;
                    for(int j=i+1;j<=n;j++)
                        if(A[j][i]!=0) id=j;
                    for(int j=i;j<=n+1;j++)
                        swap(A[i][j],A[id][j]);
                }
                for(int j=i+1;j<=n;j++){
                    double t=A[j][i]/A[i][i];
                    for(int k=i;k<=n+1;k++)
                        A[j][k]-=(A[i][k]*t);
                }
            }
            for(int i=n;i>=1;i--){
                for(int j=i+1;j<=n;j++)
                    A[i][n+1]-=ans[j]*A[i][j];
                ans[i]=A[i][n+1]/A[i][i];
            }
        }
        void gao(){
            queue<int>q;
            for(int i=1;i<=6;i++) if(son[0][i]) fail[son[0][i]]=0,q.push(son[0][i]);
            while(!q.empty()){
                int u=q.front();q.pop();
                ed[u]|=ed[fail[u]];
                for(int i=1;i<=6;i++){
                    if(son[u][i]){
                        fail[son[u][i]]=son[fail[u]][i];
                        q.push(son[u][i]);
                    }else son[u][i]=son[fail[u]][i];
                }
            }
            memset(A,0,sizeof A);
            memset(ans,0,sizeof ans);
            A[1][tot+1]=-1.0;
            for(int i=0;i<tot;i++){
                A[i+1][i+1]=-1.0;
                if(ed[i]) continue;
                for(int j=1;j<=6;j++){
                    A[son[i][j]+1][i+1]+=1.0/6;
                }
            }
            gauss(tot);
        }
    }AC;
    int main(){
        //ios::sync_with_stdio(false);
        //freopen("in","r",stdin);
        scanf("%d",&T);
        while(T--){
            AC.init();
            scanf("%d%d",&n,&m);
            for(int i=1;i<=n;i++){
                for(int i=0;i<m;i++) scanf("%d",&a[i]);
                AC.ins(i);
            }
            AC.gao();
            for(int i=1;i<=n;i++) printf("%.6f%c",ans[b[i]+1],i==n?'
    ':' ');
        }
        return 0;
    }
    
  • 相关阅读:
    pycharm+Locust搭建性能测试框架和执行环境
    mapbox构建3D建筑展示
    搭建自动化测试平台 (selenium+testng+maven+svn+Jenkins)
    chromedriver与chrome各版本及下载地址
    python的位置参数、默认参数、关键字参数、可变参数区别
    ArcMap10.5几何网络分析术语
    CSS 水平居中
    行内元素的padding和margin是否有效
    一个未知宽高的元素在div中垂直水平居中
    CSS 3-浮动、定位
  • 原文地址:https://www.cnblogs.com/xyq0220/p/13899579.html
Copyright © 2011-2022 走看看