UVA 11468AC自动机+DP
Posted Dirge
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UVA 11468AC自动机+DP相关的知识,希望对你有一定的参考价值。
dp[i][j]表示走了i步走到j结点的概率。初始值dp[0][0] = 1.当走到的结点不是单词尾结点时,才能走过去。
!end[i]&&last[i] == root时,该结点才可行。
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int N = 505; 4 int id(char c){ 5 if(c >= ‘0‘&&c <= ‘9‘) return c-‘0‘; 6 if(c >= ‘a‘&&c <= ‘z‘) return c-‘a‘+10; 7 if(c >= ‘A‘&&c <= ‘Z‘) return c-‘A‘+36; 8 return -1; 9 } 10 struct Tire{ 11 int nex[N][62], fail[N],end[N], last[N]; 12 int root, L; 13 int newnode(){ 14 memset(nex[L], -1, sizeof(nex[L])); 15 end[L] = 0; 16 return L++; 17 } 18 void init(){ 19 L = 0; 20 root = newnode(); 21 } 22 void insert(char* s){ 23 int now = root; 24 for(int i = 0; s[i]; i++){ 25 int p = id(s[i]); 26 if(nex[now][p] == -1) 27 nex[now][p] = newnode(); 28 now = nex[now][p]; 29 } 30 end[now] = 1; 31 } 32 void build(){ 33 queue<int> Q; 34 fail[root] = last[root] = root; 35 for(int i = 0; i < 62; i++){ 36 int& u = nex[root][i]; 37 if(u == -1) 38 u = root; 39 else{ 40 fail[u] = last[u] = root; 41 Q.push(u); 42 } 43 } 44 while(!Q.empty()){ 45 int now = Q.front(); 46 Q.pop(); 47 for(int i = 0; i < 62; i++){ 48 int& u = nex[now][i]; 49 if(u == -1) 50 u = nex[ fail[now] ][i]; 51 else{ 52 fail[u] = nex[ fail[now] ][i]; 53 last[u] = end[ fail[u] ]? fail[u] : last[ fail[u] ]; 54 Q.push(u); 55 } 56 } 57 } 58 } 59 }; 60 Tire ac; 61 double por[70]; 62 char s[50]; 63 double dp[105][N]; 64 int main(){ 65 int n, k, t, ca = 1; scanf("%d", &t); 66 while(t--){ 67 ac.init(); 68 scanf("%d", &k); 69 for(int i = 0; i < k; i++){ 70 scanf("%s", s); 71 ac.insert(s); 72 } 73 ac.build(); 74 memset(por, 0, sizeof(por)); 75 scanf("%d", &n); 76 char ch; 77 for(int i = 0; i < n; i++){ 78 scanf(" %c", &ch); 79 int p = id(ch); 80 scanf("%lf", por+p); 81 } 82 int l; scanf("%d", &l); 83 memset(dp, 0, sizeof(dp)); 84 dp[0][0] = 1; 85 for(int i = 0; i < l; i++){ 86 for(int j = 0; j < ac.L; j++) 87 if(dp[i][j] > 0) for(int k = 0; k < 62; k++){ 88 int ret = ac.nex[j][k]; 89 if(!ac.end[ret]&&ac.last[ret] == ac.root) 90 dp[i+1][ret] += dp[i][j]*por[k]; 91 } 92 } 93 double ans = 0; 94 for(int i = 0; i < ac.L; i++) 95 ans += dp[l][i]; 96 printf("Case #%d: %f\n", ca++, ans); 97 } 98 return 0; 99 }
以上是关于UVA 11468AC自动机+DP的主要内容,如果未能解决你的问题,请参考以下文章
UVA 11468 Substring (记忆化搜索 + AC自动鸡)