POJ 3691 DNA repair

来源:互联网 发布:杭州树熊网络怎么样 编辑:程序博客网 时间:2024/06/05 03:26

AC自动机+动态规划

具体题解

我的AC代码:

#include<cstdio>#include<cstring>#include<iostream>#include<iomanip>#include<queue>#include<cmath>#include<stack>#include<map>#include<vector>#include<set>#include<algorithm>using namespace std;int n,sz;int ch[1100][4],f[1100],val[1100],last[1100],dp[1050][1050];int zhuanhuan (char c){    if(c=='A') return 0;    if(c=='C') return 1;    if(c=='G') return 2;    if(c=='T') return 3;    return 4;}void insert (char* c){    int i = 0;    int len = strlen(c);    for(int j = 0; j < len; j++){        int u = zhuanhuan(c[j]);        if(!ch[i][u]){            memset(ch[sz], 0, sizeof(ch[sz]));            ch[i][u] = sz;            sz++;        }        i = ch[i][u];    }    val[i] = 1;}void fail (){    queue<int> q;    for(int i = 0; i < 4; i++){        if(ch[0][i]){            q.push(ch[0][i]);            f[ch[0][i]] = 0;        }    }    while(!q.empty()){        int u = q.front();        q.pop();        for(int i = 0; i < 4; i++){            if(ch[u][i]){                int t = ch[u][i];                int p = f[u];                while(p && !ch[p][i]) p = f[p];                f[t] =ch[p][i];                last[t] = (val[f[t]] ? f[t] : last[f[t]]);                q.push(t);            }        }    }}void init(){    sz = 1;    memset(ch[0], 0, sizeof(ch[0]));    memset(f, 0, sizeof(f));    memset(last, 0, sizeof(last));    memset(val, 0, sizeof(val));    for(int i = 0; i < n; i++){        char c[25];        scanf("%s", c);        insert(c);    }}int main(int argc, const char * argv[]){    int num = 1;    while(scanf("%d", &n)!=EOF){        if(n==0) break;        init();        fail();        char cs[1050];        scanf("%s", cs);        memset(dp, -1, sizeof(dp));        dp[0][0] = 0;        int len = strlen(cs);        for(int i = 0; i < len; i++){            for(int j = 0; j < sz; j++){                if(dp[i][j]!=-1){                    int u = zhuanhuan(cs[i]);                    for(int k = 0; k < 4; k++){                        int jj;                        if(ch[j][k]) jj = ch[j][k];                        else{                            int p = f[j];                            while(p && !ch[p][k]) p = f[p];                            jj = ch[p][k];                        }                        if(val[jj] || last[jj]!=0) continue;                        if(k==u){                            dp[i+1][jj] = (dp[i+1][jj]==-1 || dp[i+1][jj]>dp[i][j] ? dp[i][j] : dp[i+1][jj]);                        }else{                            dp[i+1][jj] = (dp[i+1][jj]==-1 || dp[i+1][jj]>dp[i][j]+1 ? dp[i][j]+1 : dp[i+1][jj]);                        }                    }                }            }        }        int ans = -1;        for(int i = 0; i < sz; i++){            if(dp[len][i] != -1){                if(ans==-1) ans = dp[len][i];                else ans = (ans > dp[len][i] ? dp[len][i] : ans);            }        }        printf("Case %d: %d\n", num++, ans);    }}


0 0