poj 3691 DNA repair

http://poj.org/problem?id=3691

AC自动机+DP

代码:

#include<iostream>

#include<cmath>

#include<cstdio>

#include<string>

#include<cstring>

#include<vector>

#include<stack>

#include<queue>

#include<set>

#include<map>

#include<algorithm>



#define LL long long



using namespace std;



const int INF=0x3f3f3f3f;

const int MOD=20090717;

const LL LMOD=100000;

const int N=1010;

const int M=1010;

const int K=4;

struct nodeTrie

{

    int v;

    int fail;

    int next[K];

    void initialize()

    {

        v=0;

        fail=-1;

        memset(next,-1,sizeof(next));

    }

}trie[M];

int cnt,root;

char s[N];

int to[M][K];

int dp[N][M];

map<char,int>mt;

int getNewNode()

{

    ++cnt;

    trie[cnt].initialize();

    return cnt;

}

void addWord(int p,char *s,int k)

{

    if(s[0]=='\0') return ;

    for(int i=0;s[i]!='\0';++i)

    {

        if(trie[p].next[mt[s[i]]]==-1)

        trie[p].next[mt[s[i]]]=getNewNode();

        p=trie[p].next[mt[s[i]]];

    }

    trie[p].v=k;

}

void init(int n)

{

    cnt=0;

    root=getNewNode();

    for(int i=1;i<=n;++i)

    {

        //gets(s);

        scanf("%s",s);

        addWord(root,s,1);

    }

}

void bfs(int p)

{

    trie[p].fail=root;

    queue<int>qt;

    qt.push(p);

    while(!qt.empty())

    {

        int y;

        int x=qt.front();qt.pop();

        for(int i=0;i<K;++i)

        if(trie[x].next[i]!=-1)

        {

            qt.push(trie[x].next[i]);

            if(x==root)

            {trie[trie[x].next[i]].fail=root;continue;}

            y=trie[x].fail;

            while(y!=root&&trie[y].next[i]==-1)

            y=trie[y].fail;

            if(trie[y].next[i]!=-1)

            trie[trie[x].next[i]].fail=trie[y].next[i];

            else

            trie[trie[x].next[i]].fail=root;

            trie[trie[x].next[i]].v|=trie[trie[trie[x].next[i]].fail].v;

        }

    }

}

void makeTo(int n,int k)

{

    for(int i=1;i<=n;++i)

    for(int j=0;j<k;++j)

    {

        int p=i;

        while(p!=root&&trie[p].next[j]==-1)

        p=trie[p].fail;

        if(trie[p].next[j]!=-1)

        to[i][j]=trie[p].next[j];

        else

        to[i][j]=root;

    }

};

int main()

{



    //freopen("data.in","r",stdin);

    mt.insert(pair<char,int>('A',0));

    mt.insert(pair<char,int>('C',1));

    mt.insert(pair<char,int>('G',2));

    mt.insert(pair<char,int>('T',3));

    int n;

    int ca=0;

    while(scanf("%d ",&n)!=EOF,n)

    {++ca;

        init(n);

        bfs(root);

        makeTo(cnt,K);

        //gets(s);

        scanf("%s",s);

        int m=strlen(s);

        memset(dp,-1,sizeof(dp));

        dp[0][1]=0;

        for(int i=0;i<m;++i)

        for(int j=1;j<=cnt;++j)

        if(dp[i][j]!=-1)

        {

            for(int w=0;w<K;++w)

            {

                int r=to[j][w];

                if(trie[r].v==1) continue;

                int tmp=(w==mt[s[i]])?0:1;

                if(dp[i+1][r]==-1||dp[i+1][r]>dp[i][j]+tmp)

                dp[i+1][r]=dp[i][j]+tmp;

                //cout<<(i+1)<<" "<<r<<" "<<dp[i+1][r]<<endl;

                //cout<<dp[i+1][r]<<endl;

            }

        }

        int ans=-1;

        for(int j=1;j<=cnt;++j)

        if(dp[m][j]!=-1)

        if(ans==-1||dp[m][j]<ans)

        ans=dp[m][j];

        printf("Case %d: %d\n",ca,ans);

    }

    return 0;

}

  

你可能感兴趣的:(AIR)