hdu2457DNA repair(ac自动机+dp)

链接

从开始节点往下走,不能走到病毒节点,如果当前状态与原始串不一样就+1,取一个最小值.

  1 #include <iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<stdlib.h>
  6 #include<vector>
  7 #include<cmath>
  8 #include<queue>
  9 #include<set>
 10 #include<string>
 11 using namespace std;
 12 #define N 1005
 13 #define LL long long
 14 #define INF 0xfffffff
 15 const double eps = 1e-8;
 16 const double pi = acos(-1.0);
 17 const double inf = ~0u>>2;
 18 const int child_num = 4;
 19 char vir[25];
 20 char s[N];
 21 class AC
 22 {
 23     private:
 24     int ch[N][child_num];
 25     int fail[N];
 26     int Q[N];
 27     int val[N];
 28     int sz;
 29     int id[128];
 30     char po[5];
 31     int dp[N][N];
 32     public:
 33     void init()
 34     {
 35         fail[0] = 0;
 36         id['A'] = 0,id['G'] = 1,id['T'] = 2,id['C'] = 3;
 37         po[0] = 'A',po[1] = 'G',po[2] = 'T',po[3] = 'C';
 38     }
 39     void reset()
 40     {
 41         memset(ch[0],0,sizeof(ch[0]));
 42         memset(val,0,sizeof(val));
 43         sz = 1;
 44     }
 45     void insert(char *a,int key)
 46     {
 47         int p = 0;
 48         for(; *a ; a++)
 49         {
 50             int d= id[*a];
 51             if(ch[p][d]==0)
 52             {
 53                 memset(ch[sz],0,sizeof(ch[sz]));
 54                 s[sz] = *a;
 55                 ch[p][d] = sz++;
 56             }
 57             p = ch[p][d];
 58         }
 59         val[p] = (1<<key);
 60     }
 61     void construct()
 62     {
 63         int i,head=0,tail = 0;
 64         for(i = 0; i  < child_num ;i++)
 65         {
 66             if(ch[0][i])
 67             {
 68                 fail[ch[0][i]] = 0;
 69                 Q[tail++] = ch[0][i];
 70             }
 71         }
 72         while(head!=tail)
 73         {
 74             int u = Q[head++];
 75             val[u]|=val[fail[u]];
 76             for(i = 0; i < child_num ; i++)
 77             {
 78                 if(ch[u][i])
 79                 {
 80                     fail[ch[u][i]] = ch[fail[u]][i];
 81                     Q[tail++] = ch[u][i];
 82                 }
 83                 else ch[u][i] = ch[fail[u]][i];
 84             }
 85         }
 86     }
 87     void work(int n,int kk)
 88     {
 89         int i,j,g;
 90         for(i = 0 ; i <= n ;i++)
 91             for(j = 0 ;j <= sz ; j++)
 92             dp[i][j] = INF;
 93         dp[0][0] = 0;
 94         for(i = 0 ; i < n ;i++)
 95         {
 96             for(j = 0 ;j < sz;  j++)
 97             {
 98                 for(g = 0 ;g < child_num ; g++)
 99                 {
100                     if(val[ch[j][g]]) continue;
101                     int o = 0;
102                     if(po[g]!=s[i]) o = 1;
103                     dp[i+1][ch[j][g]] = min(dp[i+1][ch[j][g]],dp[i][j]+o);
104                 }
105             }
106         }
107         int ans = INF;
108         for(i = 0 ;i < sz ; i++)
109         ans = min(ans,dp[n][i]);
110         printf("Case %d: ",kk);
111         if(ans==INF)
112         puts("-1");
113         else
114         printf("%d\n",ans);
115     }
116 }ac;
117 int main()
118 {
119     int i,m,kk=0;
120     ac.init();
121     while(scanf("%d",&m)&&m)
122     {
123         ac.reset();
124         for(i = 1;i <= m ;i++)
125         {
126             scanf("%s",vir);
127             ac.insert(vir,1);
128         }
129         ac.construct();
130         scanf("%s",s);
131         int k = strlen(s);
132         ac.work(k,++kk);
133     }
134     return 0;
135 }
View Code

 

posted @ 2014-05-25 09:37  _雨  阅读(220)  评论(0编辑  收藏  举报