zoukankan      html  css  js  c++  java
  • bzoj1444 有趣的游戏(AC自动机+矩阵乘法)

    多串比较,又和概率相关,一定是AC自动机维护概率dp

    但会发现dp转移顺序一言难尽。。。

    于是考虑把方程放到矩阵中高斯消元

    但你又会发现,有个偷懒的做法,就是把得到的矩阵自乘,乘上很多次便可无限接近答案

    数据小,不卡精,水果。。。

     1 #include<queue>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 using namespace std;
     6 int n,m,len,cnt,tot;
     7 char s[15];
     8 int pos[15];
     9 bool ed[105];
    10 double p[15];
    11 struct Trie{
    12     int son[10];
    13     int fail;
    14 }tr[105];
    15 struct node{
    16     double f[105][105];
    17 }ans;
    18 void build(char a[],int mrk){
    19     int now=0;
    20     for(int i=1;i<=len;i++){
    21         int k=a[i]-'A';
    22         if(!tr[now].son[k])tr[now].son[k]=++tot;
    23         now=tr[now].son[k];
    24     }
    25     ed[now]=true;
    26     pos[mrk]=now;
    27 }
    28 void getfail(){
    29     queue<int>que;
    30     for(int i=0;i<10;i++){
    31         if(tr[0].son[i])que.push(tr[0].son[i]);
    32     }
    33     while(!que.empty()){
    34         int u=que.front();
    35         que.pop();
    36         for(int i=0;i<10;i++){
    37             if(tr[u].son[i]){
    38                 tr[tr[u].son[i]].fail=tr[tr[u].fail].son[i];
    39                 que.push(tr[u].son[i]);
    40             }
    41             else tr[u].son[i]=tr[tr[u].fail].son[i];
    42         }
    43     }
    44 }
    45 void get_squ(){
    46     for(int i=0;i<=tot;i++){
    47         if(ed[i]){
    48             ans.f[i][i]=1;
    49             continue;
    50         }
    51         for(int j=0;j<10;j++){
    52             ans.f[i][tr[i].son[j]]+=p[j];
    53         }
    54     }
    55 }
    56 void mul(){
    57     node c;
    58     for(int i=0;i<=tot;i++){
    59         for(int j=0;j<=tot;j++){
    60             c.f[i][j]=0.00;
    61         }
    62     }
    63     for(int i=0;i<=tot;i++){
    64         for(int j=0;j<=tot;j++){
    65             for(int k=0;k<=tot;k++){
    66                 c.f[i][j]+=ans.f[i][k]*ans.f[k][j];
    67             }
    68         }
    69     }
    70     for(int i=0;i<=tot;i++){
    71         for(int j=0;j<=tot;j++){
    72             ans.f[i][j]=c.f[i][j];
    73         }
    74     }
    75 }
    76 int main(){
    77     scanf("%d%d%d",&n,&len,&m);
    78     for(int i=1;i<=m;i++){
    79         int x,y;
    80         scanf("%d%d",&x,&y);
    81         p[i-1]=(double)x/(double)y;
    82     }
    83     for(int i=1;i<=n;i++){
    84         scanf("%s",s+1);
    85         build(s,i);
    86     }
    87     getfail();get_squ();
    88     for(int i=1;i<=50;i++)mul();
    89     for(int i=1;i<=n;i++){
    90         printf("%.2lf
    ",ans.f[0][pos[i]]);
    91     }
    92     return 0;
    93 }
  • 相关阅读:
    A1126 Eulerian Path (25分)
    A1125 Chain the Ropes (25分)
    A1124 Raffle for Weibo Followers (20分)
    A1123 Is It a Complete AVL Tree (30分)
    A1122 Hamiltonian Cycle (25分)
    A1121 Damn Single (25分)
    A1120 Friend Numbers (20分)
    A1119 Pre- and Post-order Traversals (30分)
    总的调试开关
    sourceInsight
  • 原文地址:https://www.cnblogs.com/lnxcj/p/10015957.html
Copyright © 2011-2022 走看看