Descriptionas Cyy and Fzz is both busy repairing the network, Sama feel a little boring because it's he who select Teemo during That game. Of cause his Teemo would stay alive since he had used the Summoner spell Flash to avoid being killed. Since There is no network available, and he wants to does something else to pass the time. He writes some strings randomly on the paper to kill the boring time.A Few minutes later he realizes that what he writes on the paper was not truly random, in fact it reflects what he was C Oncerned about. Then he comes up with a question, what's the expect number of interesting strings that would appear in the random string h E writes? (The characters Sama writes is all lowercase Latin letters, in this problem we consider the probability so each charact Er appears as the same, that's, 1/26)Inputthe first line is a integer t (t <=) indicates the case numbers.
Then followed by T test cases. The first line of all test case contains integers n and l (n <= 8, L <=), the number of interesting strings a nd the length of the string that Sama writes, then followed by n lines, the interesting strings. We promise The interesting string is not longer than 12. (Notice, there may exist, or more same strings among the n interesting strings.)
Outputfor each test case output one line, the expect number of interesting strings that would appear in the string Sama WRI TES (accurate to 6 digits after the decimal point). Sample INPUT3
1 1
A
3 4
Cyy
Fzz
sama
8 14
Fatezero
Nisekoi
Nogamenolife
Monthlygirls
Nozakikun
Datealive
Sakura
Sorasample Output0.038462
0.000230
0.000024HintAutomaton +DP:using a walking string to construct the automaton, state compression Dp[i][j][k]: Indicates the length of I, walk to the Automaton J node, string containing case Kprobability. The answer is to ask for the expectation.
#include <cstdio> #include <cstring> #include <algorithm> #include <vector> #include <string > #include <iostream> #include <queue> #include <cmath> #include <map> #include <stack> #include <bitset>using namespace std; #define REPF (I, A, b) for (int i = A; I <= B; + + i) #define REP (i, n ) for (int i = 0; i < n; + + i) #define CLEAR (A, X) memset (A, x, sizeof a) typedef long long Ll;typedef pair& lt;int,int>pil;const int INF = 0x3f3f3f3f;double dp[20][110][(1<<8) +10];int t,n,l;struct AC{int next[110][26] ; int fail[110],ed[110]; int root,l; int NewNode () {for (int i=0;i<26;i++) next[l][i]=-1; ed[l++]=0; return L-1; } void Init () {l=0; Root=newnode (); } void Insert (char buf[],int ID) {int len=strlen (BUF); int now=root; for (int i=0;i<len;i++) {int x=buf[i]-' a '; if (next[now][x]==-1) Next[now][x]=newnode (); NOW=NEXT[NOW][X]; } ed[now]|= (1<<id); } void Build_ac () {queue<int>q; Fail[root]=root; for (int i=0;i<26;i++) {if (next[root][i]==-1) next[root][i]=root; else {fail[next[root][i]]=root; Q.push (Next[root][i]); }} while (!q.empty ()) {int Now=q.front (); Q.pop (); Ed[now]|=ed[fail[now]]; for (int i=0;i<26;i++) {if (next[now][i]==-1) next[now][i]=next[fail[now]][ I]; else {fail[next[now][i]]=next[fail[now]][i]; Q.push (Next[now][i]); }}}} void Solve () {CLEAR (dp,0); dp[0][0][0]=1.0; for (int i=0;i<l;i++) {for (int j=0;j<l;j++) {for (int k=0;k< (1<<n); k++) {if (dp[i][j][k]!=0) {for (int h=0;h<26;h++) {int now=next[j ][H]; DP[I+1][NOW][ED[NOW]|K]+=1.0/26*DP[I][J][K]; }}}}} double ans=0; for (int i=0;i<l;i++) {for (int j=0;j< (1<<n); j + +) {int cnt=0; for (int k=0;k<26;k++) if (j& (1<<k)) cnt++; ANS+=CNT*DP[L][I][J]; }} printf ("%.6f\n", ans); }}; AC A;int Main () {char str[20]; scanf ("%d", &t); while (t--) {a.init (); scanf ("%d%d", &n,&l); REP (i,n) {scanf ("%s", str); A.insert (Str,i); } a.build_ac (); A.solve (); } return 0;} /*31 1a3 4cyyfzzsama8 14fatezeronisekoinogamenolifemonthlygirlsnozakikundatealivesakurasora*/
WHU 1572 Cyy and Fzz (Automaton +DP)