首页 > 代码库 > hdu 5955 Guessing the Dice Roll 【AC自动机+高斯消元】

hdu 5955 Guessing the Dice Roll 【AC自动机+高斯消元】

hdu 5955 Guessing the Dice Roll 【AC自动机+高斯消元】

题意:给出 n≤10 个长为 L≤10 的串,每次丢一个骰子,先出现的串赢,问获胜概率。

题解:裸的AC自动机,求匹配到终止结点的概率,用 高斯消元?一开始不知道怎么建方程组,直接举个例子吧:

Input:

1

2 2

1 1

2 1

图解:

技术分享

x0原本概率就是1,然后还要加上其他结点走向它的概率,,这样最后算下来是大于1的,现在还是觉得怪怪的。。。技术分享

  1 #include <cstdio>  2 #include <algorithm>  3 #include <cstring>  4 #include <queue>  5 #define CLR(a,b) memset((a),(b),sizeof((a)))  6 using namespace std;  7 const int N = 105;  8 const int M = 6;  9 int equ, var; 10 double a[N][N]; 11 double x[N]; 12 void Gauss() { 13     int i, j, k; 14     int max_r; 15     int col; 16     for(col = 0, k = 0; k < equ && col < var; ++k, ++col) { 17         max_r = k; 18         for(i = k+1; i < equ; ++i) 19             if(fabs(a[i][col]) > fabs(a[max_r][col])) 20                 max_r = i; 21         if(max_r != k) { 22             for(j = k; j < var; ++j) 23                 swap(a[k][j], a[max_r][j]); 24                swap(x[k], x[max_r]); 25         } 26         x[k] /= a[k][col]; 27         for(j = col+1; j < var; ++j) 28             a[k][j] /= a[k][col]; 29         a[k][col] = 1; 30         for(i = 0; i < equ; ++i) { 31             if(i != k) { 32                 x[i] -= x[k] * a[i][col]; 33                 for(j = col+1; j < var; ++j) 34                     a[i][j] -= a[k][j] * a[i][col]; 35                 a[i][col] = 0; 36             } 37         } 38     } 39 } 40 int mk[N]; 41 struct Trie { 42     int next[N][M], fail[N], tag[N]; 43     int root, L; 44     int newnode() { 45         for(int i = 0;i < M;i++) 46             next[L][i] = -1; 47         tag[L++] = 0; 48         return L-1; 49     } 50     void init() { L = 0; root = newnode(); } 51     void Insert(int buf[], int len, int id) { 52         int u = root; 53         for(int i = 0; i < len; i++) { 54             if(next[u][buf[i]] == -1) 55                 next[u][buf[i]] = newnode(); 56             u = next[u][buf[i]]; 57         } 58         tag[u] = 1; 59         mk[id] = u; 60     } 61     void build() { 62         queue<int> Q; 63         fail[root] = root; 64         for(int i = 0; i < M; i++) { 65             if(next[root][i] == -1) 66                 next[root][i] = root; 67             else { 68                 fail[next[root][i]] = root; 69                 Q.push(next[root][i]); 70             } 71         } 72         while( !Q.empty() ) { 73             int u = Q.front(); 74             Q.pop(); 75             for(int i = 0; i < M; i++) { 76                 int &v = next[u][i]; 77                 if(v == -1) 78                     v = next[fail[u]][i]; 79                 else { 80                     Q.push(v); 81                     fail[v] = next[fail[u]][i]; 82                 } 83             } 84         } 85     } 86     void query(int n) { 87         int i , j; 88         CLR(a, 0); CLR(x, 0); 89         equ = var = L; 90         for(i = 0; i < L; ++i) a[i][i] = -1.0; 91         x[0] = -1.0; 92         for(i = 0; i < L; ++i) { 93             for(j = 0; j < M; ++j) { 94                 if(next[i][j] != -1 && tag[i]==0) 95                     a[next[i][j]][i] += 1.0/6; 96             } 97         } 98         Gauss(); 99         for(i = 0; i < n-1; ++i)100             printf("%.6f ", x[mk[i]]);101         printf("%.6f\n", x[mk[n-1]]);102     }103 };104 Trie ac;105 int main() {106     int T, n, m;107     int A[15];108     scanf("%d",&T);109     while( T-- ) {110         scanf("%d%d", &n, &m);111         ac.init();112         for(int i = 0; i < n; i++) {113             for(int j = 0; j < m; ++j) {114                 scanf("%d", &A[j]);115                 A[j]--;    //0~5116             }117             ac.Insert(A, m, i);118         }119         ac.build();120         ac.query(n);121     }122     return 0;123 }

 

hdu 5955 Guessing the Dice Roll 【AC自动机+高斯消元】