woj1572 Cyy and Fzz kmp/ac automata + DP

Source: Internet
Author: User

Title: http://acm.whu.edu.cn/land/problem/detail?problem_id=1572

Test instructions: There are n target string, the length is less than four, (n<=8), now randomly write a string length of L, asked to write this string contains the target string of the expected number.


The game was thought to be a water problem, in fact, they are too water. This kind of problem is generally the medium problem of AC automata, the subject can also be done with KMP, combined with pressure DP.


Method one: AC automatic machine

After the completion of the trie tree, is to run the DP, note that the word node to |= (1<<val), there will be a heavy string.

DP process: With DP[I][J][K] in the Automaton node I, the current remaining J step, has a State of K (k is a binary number) probability.

The transfer is the enumeration of the next character, and the current I point will follow the next array toward now= Next[i][ch]

dp[now][j-1][K|end[now]] + = dp[i][j][k] * (1.0/26)

The last statistic will do.

Code:

#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include < queue>using namespace Std;const int max_n = 105;const int ALP = 26;const int N = 15;struct trie{int Next[max_n][alp    ], Fail[max_n], end[max_n];    int root, L;        int NewNode () {for (int i=0;i<alp;i++) Next[l][i] =-1;        end[l++] = 0;    return L-1;        } void Init () {memset (end,0,sizeof (end));        L = 0;    root = NewNode ();        } void Insert (char* buf, int id) {int now = root;        int len = strlen (BUF);            for (int i=0;i<len;i++) {int ch = buf[i]-' a ';            if (next[now][ch]==-1) next[now][ch] = NewNode ();        now = Next[now][ch];    } End[now] |= 1<< (id-1);        } void Build () {queue<int> Q;        Fail[root] = root;            for (int i=0;i<alp;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 ();                for (int i=0;i<alp;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]);    }}}} double dp[max_n][n][(1<<8) +5]; Double Get_ans (int n,int step) {for (int i=step;i>=0;i--) for (int. j=0;j<l;j++) for (int k=0;k<        (1<<n); k++) dp[j][i][k] = 0;        Dp[0][step][0] = 1.0;        for (int i=step;i>=1;i--) for (int. j=0;j<l;j++) for (int k=0;k< (1<<n); k++) if (dp[j][i][k]>0)            for (int. p=0;p<26;p++) {int now = next[j][p];            int state = 0;            int tmp = now;       while (tmp!=root) {State |= end[tmp];         TMP = fail[tmp];        } Dp[now][i-1][k|state] + = dp[j][i][k]* (1.0/26);        } double ret = 0;            for (int i=0;i<l;i++) for (int k=1;k< (1<<n); k++) if (dp[i][0][k]>0) {int EP = 0; for (int p=0;p<n;p++) if (k& (1<<p)) ep++;//printf ("Node%d state%d num%d p=%f\n", I            , K,ep,dp[i][0][k]);        RET + = Ep*dp[i][0][k];    } return ret;    }}ac;char S[15];int Main () {int t,n,l;    Cin >> T;        while (t--) {scanf ("%d%d", &n,&l);        Ac.init ();            for (int i=1;i<=n;i++) {scanf ("%s", s);        Ac.insert (S,i); } ac.build ();//printf ("numl =%d n L%d%d\n", AC.        L,N,L);        Double ans = ac.get_ans (n,l);    printf ("%.6f\n", ans); } return 0;}


-----------------------------------------------------

Method Two: KMP

Since each target string is independent, it is possible to count the expectations of each target string separately and accumulate.

So for a single string only to get the probability that cannot contain it, its contribution is 1-p.

Also dp:dp[i][j] indicates that the match to the I-bit (I did not match successfully) also has the remaining J step, which cannot contain the probability of this string.

The shift is to enumerate the next character, along the fail function to the next position in the maximum match position now

DP[NOW][J] + = dp[i][j] * (1.0/26)

Statistical contributions and for each goal string.

Code:

#include <iostream> #include <cstdio> #include <cstring> #include <algorithm>using namespace    std;const int max_n = 20;struct kmp{char p[max_n];    int Fail[max_n],len;        void Get_fail () {len = strlen (P);        Fail[0] = fail[1] = 0;            for (int i=1;i<len;i++) {int j = fail[i];            while (J && p[j]!=p[i]) j = fail[j]; FAIL[I+1] = P[j]==p[i]?        j+1:0;    }} double dp[max_n][15];        Double Get_ans (int L) {memset (dp,0,sizeof (DP));        DP[0][L] = 1.0;  for (int i=l;i>=1;i--) for (int j=0;j<len;j++) {for (int k=0;k<26;k++) {if (j==len-1                && p[len-1]== ' a ' +k) continue;                int now = j;                if (p[j]== ' a ' +k) now = j+1;                    else{while (now && p[now]!= ' a ' +k) now = Fail[now];                if (p[now]== ' a ' +k) now++;          } Dp[now][i-1] + = dp[j][i]* (1.0/26);  }} double ans = 1.0;        for (int i=0;i<len;i++) ans-= dp[i][0];    return ans;    }}km;int Main () {int t,n,l;    Cin >> T;        while (t--) {scanf ("%d%d", &n,&l);        Double ans = 0; for (int i=1;i<=n;i++) {scanf ('%s '), KM.            P);            Km.get_fail ();        Ans + = Km.get_ans (L);    } printf ("%.6f\n", ans); } return 0;}



Through this problem or more in-depth understanding of the KMP and AC automata.

Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.

woj1572 Cyy and Fzz kmp/ac automata + DP

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.