方法:ac自动机 dp
方法比较明显,dp[cur][left] 表示在cur结点,能走left步的期望。在ac自动机上记忆化搜索即可。注意,判断下一个结点nxt是否可行,要看val[nxt] 和 last[nxt]。所以在get fail 的时候,也可省去last,直接 val[nxt] |= val[f[nxt]]。(val[i] = 1 代表 i结点为某个禁止串的终点,=0则不是)。
code:
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <iostream> 5 #include <string> 6 #include <vector> 7 #include <stack> 8 #include <bitset> 9 #include <cstdlib> 10 #include <cmath> 11 #include <set> 12 #include <list> 13 #include <deque> 14 #include <map> 15 #include <queue> 16 #include <fstream> 17 #include <cassert> 18 #include <unordered_map> 19 #include <unordered_set> 20 #include <cmath> 21 #include <sstream> 22 #include <time.h> 23 #include <complex> 24 #include <iomanip> 25 #define Max(a,b) ((a)>(b)?(a):(b)) 26 #define Min(a,b) ((a)<(b)?(a):(b)) 27 #define FOR(a,b,c) for (ll (a)=(b);(a)<(c);++(a)) 28 #define FORN(a,b,c) for (ll (a)=(b);(a)<=(c);++(a)) 29 #define DFOR(a,b,c) for (ll (a)=(b);(a)>=(c);--(a)) 30 #define FORSQ(a,b,c) for (ll (a)=(b);(a)*(a)<=(c);++(a)) 31 #define FORC(a,b,c) for (char (a)=(b);(a)<=(c);++(a)) 32 #define FOREACH(a,b) for (auto &(a) : (b)) 33 #define rep(i,n) FOR(i,0,n) 34 #define repn(i,n) FORN(i,1,n) 35 #define drep(i,n) DFOR(i,n-1,0) 36 #define drepn(i,n) DFOR(i,n,1) 37 #define MAX(a,b) a = Max(a,b) 38 #define MIN(a,b) a = Min(a,b) 39 #define SQR(x) ((LL)(x) * (x)) 40 #define Reset(a,b) memset(a,b,sizeof(a)) 41 #define fi first 42 #define se second 43 #define mp make_pair 44 #define pb push_back 45 #define all(v) v.begin(),v.end() 46 #define ALLA(arr,sz) arr,arr+sz 47 #define SIZE(v) (int)v.size() 48 #define SORT(v) sort(all(v)) 49 #define REVERSE(v) reverse(ALL(v)) 50 #define SORTA(arr,sz) sort(ALLA(arr,sz)) 51 #define REVERSEA(arr,sz) reverse(ALLA(arr,sz)) 52 #define PERMUTE next_permutation 53 #define TC(t) while(t--) 54 #define forever for(;;) 55 #define PINF 1000000000000 56 #define newline ' ' 57 58 #define test if(1)if(0)cerr 59 using namespace std; 60 using namespace std; 61 typedef vector<int> vi; 62 typedef vector<vi> vvi; 63 typedef pair<int,int> ii; 64 typedef pair<double,double> dd; 65 typedef pair<char,char> cc; 66 typedef vector<ii> vii; 67 typedef long long ll; 68 typedef unsigned long long ull; 69 typedef pair<ll, ll> l4; 70 const double pi = acos(-1.0); 71 72 const int MAXNODE = 20*20+5; 73 const int SIGMA_SIZE = 130; 74 const int MAXL = 105; 75 inline int idx(char c) 76 { 77 return c; 78 } 79 80 struct AC 81 { 82 int g[MAXNODE][SIGMA_SIZE], val[MAXNODE], last[MAXNODE], f[MAXNODE]; 83 int sz; 84 int newnode() 85 { 86 Reset(g[sz], 0); 87 val[sz] = last[sz] = 0; 88 return sz++; 89 } 90 void init() 91 { 92 sz = 0; newnode(); 93 } 94 void insert(const string &str, int v) 95 { 96 int u = 0, n = str.length(); 97 rep(i, n) 98 { 99 int c = idx(str[i]); 100 if (!g[u][c]) g[u][c] = newnode(); 101 u = g[u][c]; 102 } 103 val[u] = v; 104 } 105 void get_fail() 106 { 107 queue<int> q; f[0] = 0; 108 rep(i, SIGMA_SIZE) 109 { 110 int u = g[0][i]; 111 if (u) 112 { 113 f[u] = last[u] = 0; q.push(u); 114 } 115 } 116 while (!q.empty()) 117 { 118 int r = q.front(); q.pop(); 119 rep(c, SIGMA_SIZE) 120 { 121 int u = g[r][c]; 122 if (!u) 123 { 124 g[r][c] = g[f[r]][c]; continue; 125 } 126 q.push(u); 127 int v = f[r]; 128 while (v && !g[v][c]) v = f[v]; 129 f[u] = g[v][c]; 130 last[u] = val[f[u]]?f[u]:last[f[u]]; 131 } 132 } 133 } 134 void valid(int j) 135 { 136 if (j) 137 { 138 valid(last[j]); 139 } 140 } 141 void find(const string &str) 142 { 143 int n = str.length(), j = 0; 144 rep(i, n) 145 { 146 int c = idx(str[i]); 147 j = g[j][c]; 148 if (val[j]) valid(j); 149 else if (last[j]) valid(last[j]); 150 } 151 } 152 }; 153 AC ac; 154 155 map<int, double> p; 156 string str; 157 int k, l, N; 158 double d[MAXNODE][MAXL]; 159 bool vis[MAXNODE][MAXL]; 160 double dp(int cur, int left) 161 { 162 if (!left) return 1.0; 163 if (!vis[cur][left]) 164 { 165 vis[cur][left] = true; 166 double &ans = d[cur][left]; 167 ans = 0; 168 for (auto &pr : p) if (!ac.val[ac.g[cur][pr.first]] && !ac.last[ac.g[cur][pr.first]]) 169 { 170 ans += pr.second*dp(ac.g[cur][pr.first], left-1); 171 } 172 } 173 return d[cur][left]; 174 } 175 int main() 176 { 177 ios::sync_with_stdio(false); 178 cin.tie(0); 179 int T; cin >> T; 180 repn(kase, T) 181 { 182 ac.init(); 183 p.clear(); 184 cin >> k; 185 rep(i, k) 186 { 187 string line; cin >> line; 188 ac.insert(line, 1); 189 } 190 ac.get_fail(); 191 cin >> N; 192 rep(i, N) 193 { 194 char c; cin >> c; 195 double temp; cin >> temp; 196 p[idx(c)] = temp; 197 } 198 cin >> l; 199 Reset(vis, 0); 200 printf("Case #%d: %.6lf ", kase, dp(0, l)); 201 } 202 }