POJ 2778 DNA Sequence (AC自動機 + dp),poj自動機

來源:互聯網
上載者:User

POJ 2778 DNA Sequence (AC自動機 + dp),poj自動機
DNA Sequence題意:DNA的序列由ACTG四個字母組成,現在給定m個不可行的序列。問隨機構成的長度為n的序列中,有多少種序列是可行的(只要包含一個不可行序列便不可行)。個數很大,對100000模數。
思路:推薦一個部落格,講的非常清楚。這種題目,n很大,首先想到的就是用矩陣來最佳化。那麼如何構造轉移方程呢:首先建立一棵Trie,然後按照AC自動機的方式構造fail指標,然後會發現,當一個狀態分別添加ACTG之後,會得到另一個狀態。 (具體解釋見代碼)
代碼:

/*ID: wuqi9395@126.comPROG:LANG: C++*/#include<map>#include<set>#include<queue>#include<stack>#include<cmath>#include<cstdio>#include<vector>#include<string>#include<fstream>#include<cstring>#include<ctype.h>#include<iostream>#include<algorithm>#define INF (1<<30)#define PI acos(-1.0)#define mem(a, b) memset(a, b, sizeof(a))#define rep(i, n) for (int i = 0; i < n; i++)#define debug puts("===============")typedef long long ll;using namespace std;const int maxn = 110;const int maxm = 110;ll mod = 100000;struct Matrix {    int n, m;    ll a[maxn][maxm];    void clear() {        n = m = 0;        memset(a, 0, sizeof(a));    }    Matrix operator * (const Matrix &b) const { //實現矩陣乘法        Matrix tmp;        tmp.clear();        tmp.n = n;        tmp.m = b.m;        for (int i = 0; i < n; i++)            for (int j = 0; j < m; j++) {                if (!a[i][j]) continue;                for (int k = 0; k < b.m; k++)                    tmp.a[i][k] += a[i][j] * b.a[j][k], tmp.a[i][k] %= mod;            }        return tmp;    }}A, res;const int maxnode = 11 * 11;const int charset = 4;struct ACAutomaton {    int ch[maxnode][charset];    int fail[maxnode];    int Q[maxnode];    int val[maxnode];    int sz;    int id(char ch) {        if (ch == 'A') return 0;        else if (ch == 'C') return 1;        else if (ch == 'T') return 2;        return 3;    }    void init() {        fail[0] = 0;        //for (int i = 0; i < charset; i++) ID[i] = i;    }    void reset() {        sz = 1;        memset(ch[0], 0, sizeof(ch[0]));    }    void Insert(char* s, int key) {        int u = 0;        for (; *s; s++) {            int c = id(*s);            if (!ch[u][c]) {                memset(ch[sz], 0, sizeof(ch[sz]));                val[sz] = 0;                ch[u][c] = sz++;            }            u = ch[u][c];        }        val[u] = key;    }    void Construct () {        int *s = Q, *e = Q;        for (int i = 0; i < charset; i++) {            if (ch[0][i]) {                *e++ = ch[0][i];                fail[ch[0][i]] = 0;            }        }        while(s != e) {            int u = *s++;            if (val[fail[u]]) val[u] = 1;            for (int i = 0; i < charset; i++) {                int &v = ch[u][i];                if (v) {                    *e++ = v;                    fail[v] = ch[fail[u]][i];                } else {                    v = ch[fail[u]][i];                }            }        }    }    /*        dp[i][j]表示長度為i,尾碼為j的狀態 最多就只有10*10個尾碼        所以可以通過dp[n][j] = a0 * dp[n-1][0] + ... + ak * dp[n - 1][k]得到狀態轉移的矩陣    */    void work() {        for (int i = 0; i < sz; i++) {            for (int j = 0; j < charset; j++) {                //對於i狀態,通過添加ACTG能夠得到新的狀態(且之前已經構造過AC自動機,ch[i][j]便表示新狀態)                if (!val[i] && !val[ch[i][j]]) { //兩個狀態都必須是可行的,轉化才有意義                    A.a[i][ch[i][j]]++;                }            }        }    }} AC;Matrix Matrix_pow(Matrix A, ll k, ll mod) {    res.clear();    res.n = res.m = AC.sz;    for (int i = 0; i < AC.sz; i++) res.a[i][i] = 1;    while(k) {        if (k & 1) res = res * A;        A = A * A;        k >>= 1;    }    return res;}int main () {    int m, n;    A.clear();    AC.init();    AC.reset();    char str[15];    scanf("%d%d", &m, &n);    for (int i = 0; i < m; i++) {        scanf("%s", str);        AC.Insert(str, 1);    }    A.n = A.m = AC.sz;    AC.Construct();    //之前的都是AC自動機構造部分    AC.work(); //得到狀態轉移的矩陣    res = Matrix_pow(A, n, mod);    int ans = 0;    rep(i, AC.sz) ans += res.a[0][i];    printf("%d\n", ans % mod);    return 0;}



助POJ2778 DNA Sequence

謝謝一個C或者C++版的,兄弟就給你看一下!
 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

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.