题意:
给出一些字符和各自对应的选择概率,随机选择L次后得到一个长度为L的随机字符串S。
给出K个模板串,计算S不包含任何一个模板串的概率
dp【i】【j】表示走到AC自动机 i 这个节点 还需要走 j 步的概率。
表示不会概率DP ,看网上题解写的。
通过记忆化搜索去写。
注意一点字符有大小字母和数字
1 #include <set> 2 #include <map> 3 #include <stack> 4 #include <queue> 5 #include <cmath> 6 #include <ctime> 7 #include <cstdio> 8 #include <string> 9 #include <vector> 10 #include <cstring> 11 #include <iostream> 12 #include <algorithm> 13 #include <unordered_map> 14 15 #define pi acos(-1.0) 16 #define eps 1e-9 17 #define fi first 18 #define se second 19 #define rtl rt<<1 20 #define rtr rt<<1|1 21 #define bug printf("****** ") 22 #define mem(a, b) memset(a,b,sizeof(a)) 23 #define name2str(x) #x 24 #define fuck(x) cout<<#x" = "<<x<<endl 25 #define sfi(a) scanf("%d", &a) 26 #define sffi(a, b) scanf("%d %d", &a, &b) 27 #define sfffi(a, b, c) scanf("%d %d %d", &a, &b, &c) 28 #define sffffi(a, b, c, d) scanf("%d %d %d %d", &a, &b, &c, &d) 29 #define sfL(a) scanf("%lld", &a) 30 #define sffL(a, b) scanf("%lld %lld", &a, &b) 31 #define sfffL(a, b, c) scanf("%lld %lld %lld", &a, &b, &c) 32 #define sffffL(a, b, c, d) scanf("%lld %lld %lld %lld", &a, &b, &c, &d) 33 #define sfs(a) scanf("%s", a) 34 #define sffs(a, b) scanf("%s %s", a, b) 35 #define sfffs(a, b, c) scanf("%s %s %s", a, b, c) 36 #define sffffs(a, b, c, d) scanf("%s %s %s %s", a, b,c, d) 37 #define FIN freopen("../in.txt","r",stdin) 38 #define gcd(a, b) __gcd(a,b) 39 #define lowbit(x) x&-x 40 #define IO iOS::sync_with_stdio(false) 41 42 43 using namespace std; 44 typedef long long LL; 45 typedef unsigned long long ULL; 46 const ULL seed = 13331; 47 const LL INFLL = 0x3f3f3f3f3f3f3f3fLL; 48 const int maxn = 1e6 + 7; 49 const int maxm = 8e6 + 10; 50 const int INF = 0x3f3f3f3f; 51 const int mod = 1e9 + 7; 52 int T, n, m, L, id[70], vis[410][110]; 53 char buf[410]; 54 double dp[410][110], pro[70]; 55 56 int get_num(char ch) { 57 if (ch >= 'a' && ch <= 'z') return ch - 'a'; 58 if (ch >= 'A' && ch <= 'Z') return ch - 'A' + 26; 59 if (ch >= '0' && ch <= '9') return ch - '0' + 52; 60 } 61 62 struct Aho_Corasick { 63 int next[410][66], fail[410], End[410]; 64 int root, cnt; 65 66 int newnode() { 67 for (int i = 0; i < 66; i++) next[cnt][i] = -1; 68 End[cnt++] = 0; 69 return cnt - 1; 70 } 71 72 void init() { 73 cnt = 0; 74 root = newnode(); 75 } 76 77 void insert(char buf[]) { 78 int len = strlen(buf); 79 int now = root; 80 for (int i = 0; i < len; i++) { 81 if (next[now][get_num(buf[i])] == -1) next[now][get_num(buf[i])] = newnode(); 82 now = next[now][get_num(buf[i])]; 83 } 84 End[now] = 1; 85 } 86 87 void build() { 88 queue<int> Q; 89 fail[root] = root; 90 for (int i = 0; i < 66; i++) 91 if (next[root][i] == -1) next[root][i] = root; 92 else { 93 fail[next[root][i]] = root; 94 Q.push(next[root][i]); 95 } 96 while (!Q.empty()) { 97 int now = Q.front(); 98 Q.pop(); 99 End[now] |= End[fail[now]]; 100 for (int i = 0; i < 66; i++) 101 if (next[now][i] == -1) next[now][i] = next[fail[now]][i]; 102 else { 103 fail[next[now][i]] = next[fail[now]][i]; 104 Q.push(next[now][i]); 105 } 106 } 107 } 108 109 double solve(int pos, int res) { 110 if (!res) return 1.0; 111 if (vis[pos][res]) return dp[pos][res]; 112 vis[pos][res] = 1; 113 double &ret = dp[pos][res]; 114 ret = 0; 115 for (int i = 0; i < m; ++i) { 116 int idx = id[i]; 117 if (!End[next[pos][idx]]) ret += pro[i] * solve(next[pos][idx], res - 1); 118 } 119 return ret; 120 } 121 122 void debug() { 123 for (int i = 0; i < cnt; i++) { 124 printf("id = %3d,fail = %3d,end = %3d,chi = [", i, fail[i], End[i]); 125 for (int j = 0; j < 26; j++) printf("%2d", next[i][j]); 126 printf("] "); 127 } 128 } 129 } ac; 130 131 int main() { 132 // FIN; 133 int cas = 1; 134 sfi(T); 135 while (T--) { 136 sfi(n); 137 ac.init(); 138 for (int i = 0; i < n; ++i) { 139 sfs(buf); 140 ac.insert(buf); 141 } 142 ac.build(); 143 sfi(m); 144 for (int i = 0; i < m; ++i) { 145 scanf("%s%lf", buf, &pro[i]); 146 id[i] = get_num(buf[0]); 147 } 148 sfi(L); 149 mem(vis, 0); 150 printf("Case #%d: %.6f ", cas++, ac.solve(0, L)); 151 } 152 return 0; 153 }