Cyy and Fzz (AC自动机+dp)

Description As Cyy and Fzz are both busy repairing the network, Sama feel a little boring because it’s he who select Teemo during that game. Of cause his Teemo will stay alive since he has used the summoner spell Flash to avoid being killed. Since there is no network available, he wants to do 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 is not truly random, in fact it reflects what he is concerned about. Then he comes up with a question, what is the expect number of interesting strings that will appear in the random string he writes? (The characters Sama writes are all lowercase Latin letters, in this problem we consider the probability that each character appears as the same, that is, 1/26) Input The first line is an integer T (T <= 13) indicates the case numbers. Then followed by T test cases. The first line of each test case contains two integers n and L(n <= 8, L <= 14), the number of interesting strings and the length of the string that Sama writes, then followed by n lines, the interesting strings. We promise that the interesting string is not longer than 12. (Notice that there may exist two or more same strings among the n interesting strings.) Output For each test case output one line, the expect number of interesting strings that will appear in the string Sama writes (Accurate to 6 digits after the decimal point). Sample Input 3 1 1 a 3 4 cyy fzz sama 8 14 fatezero nisekoi nogamenolife monthlygirls nozakikun datealive sakura sora Sample Output 0.038462 0.000230 0.000024 Hint

dp[i][j][sta] 表示长度为i,在节点j,包含串的状态为sta的概率,最后求出期望就行

/*************************************************************************> File Name: I.cpp> Author: ALex> Mail: zchao1995@gmail.com> Created Time: 2015年04月19日 星期日 16时09分56秒 ************************************************************************/;const double pi = acos(-1.0);const int inf = 0x3f3f3f3f;const double eps = 1e-15;LL;typedef pair <int, int> PLL;const int MAX_NODE = 200;const int CHILD_NUM = 26;double dp[20][MAX_NODE][300];struct AC_Automation{int next[MAX_NODE][CHILD_NUM];int fail[MAX_NODE];int end[MAX_NODE];int root, L;int newnode(){for (int i = 0; i < CHILD_NUM; ++i){next[L][i] = -1;}end[L++] = 0;return L – 1;}void init (){L = 0;root = newnode();}void Build_Trie (char buf[], int id){int now = root;int len = strlen (buf);for (int i = 0; i < len; ++i){if (next[now][buf[i] – ‘a’] == -1){next[now][buf[i] – ‘a’] = newnode();}now = next[now][buf[i] – ‘a’];}end[now] |= (1 << id);}void Build_AC (){queue <int> qu;fail[root] = root;for (int i = 0; i < CHILD_NUM; ++i){if (next[root][i] == -1){next[root][i] = root;}else{fail[next[root][i]] = root;qu.push (next[root][i]);}}while (!qu.empty()){int now = qu.front();qu.pop();end[now] |= end[fail[now]];for (int i = 0; i < CHILD_NUM; ++i){if (next[now][i] == -1){next[now][i] = next[fail[now]][i];}else{fail[next[now][i]] = next[fail[now]][i];qu.push(next[now][i]);}}}}void solve(int n, int m){memset(dp, 0, sizeof(dp));dp[0][0][0] = 1;for (int i = 0; i < m; ++i){for (int j = 0; j < L; ++j){for (int sta = 0; sta < (1 << n); ++sta){if (dp[i][j][sta]){for (int k = 0; k < CHILD_NUM; ++k){int nxt = next[j][k];dp[i + 1][nxt][end[nxt] | sta] += (1.0 / 26) * dp[i][j][sta];}}}}}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 < n; ++k){if (j & (1 << k)){++cnt;}}ans += cnt * dp[m][i][j];}}printf(“%f\n”, ans);}}AC;char str[50];int main(){int t;scanf(“%d”, &t);while (t–){int n, L;scanf(“%d%d”, &n, &L);AC.init();for (int i = 0; i < n; ++i){scanf(“%s”, str);AC.Build_Trie(str, i);}AC.Build_AC();AC.solve(n, L);}return 0;}

,不要忘本,任何时候,任何事情。

Cyy and Fzz (AC自动机+dp)

相关文章:

你感兴趣的文章:

标签云: