码迷,mamicode.com
首页 > 其他好文 > 详细

HDU2457 DNA repair(AC自动机+DP)

时间:2016-01-30 02:02:34      阅读:210      评论:0      收藏:0      [点我收藏+]

标签:

题目一串DNA最少需要修改几个基因使其不包含一些致病DNA片段。

这道题应该是AC自动机+DP的入门题了,有POJ2778基础不难写出来。

dp[i][j]表示原DNA前i位(在AC自动机上转移i步)且后缀状态为AC自动机结点j的最少需要修改的基因数

转移我为人人型,从dp[i][j]向ATCG四个方向转移到dp[i+1][j‘],如果结点被标记包含致病基因就不能转移。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<queue>
 4 using namespace std;
 5 #define INF (1<<30)
 6 int tn,ch[1111][4],fail[1111],idx[128];
 7 bool flag[1111];
 8 void insert(char *s){
 9     int x=0;
10     for(int i=0; s[i]; ++i){
11         int y=idx[s[i]];
12         if(ch[x][y]==0) ch[x][y]=++tn;
13         x=ch[x][y];
14     }
15     flag[x]=1;
16 }
17 void init(){
18     memset(fail,0,sizeof(fail));
19     queue<int> que;
20     for(int i=0; i<4; ++i){
21         if(ch[0][i]) que.push(ch[0][i]);
22     }
23     while(!que.empty()){
24         int x=que.front(); que.pop();
25         for(int i=0; i<4; ++i){
26             if(ch[x][i]) que.push(ch[x][i]),fail[ch[x][i]]=ch[fail[x]][i];
27             else ch[x][i]=ch[fail[x]][i];
28             flag[ch[x][i]]|=flag[ch[fail[x]][i]];
29         }
30     }
31 }
32 int d[1111][1111];
33 int main(){
34     idx[A]=0; idx[G]=1; idx[C]=2; idx[T]=3;
35     char str[1111];
36     int n,t=0;
37     while(~scanf("%d",&n) && n){
38         tn=0;
39         memset(ch,0,sizeof(ch));
40         memset(flag,0,sizeof(flag));
41         while(n--){
42             scanf("%s",str);
43             insert(str);
44         }
45         init();
46         scanf("%s",str+1);
47         n=strlen(str+1);
48         for(int i=0; i<=n; ++i){
49             for(int j=0; j<=tn; ++j) d[i][j]=INF;
50         }
51         d[0][0]=0;
52         for(int i=0; i<n; ++i){
53             for(int j=0; j<=tn; ++j){
54                 if(d[i][j]==INF || flag[j]) continue;
55                 for(int k=0; k<4; ++k){
56                     if(flag[ch[j][k]]) continue;
57                     if(idx[str[i+1]]==k) d[i+1][ch[j][k]]=min(d[i+1][ch[j][k]],d[i][j]);
58                     else d[i+1][ch[j][k]]=min(d[i+1][ch[j][k]],d[i][j]+1);
59                 }
60             }
61         }
62         int res=INF;
63         for(int i=0; i<=tn; ++i) res=min(res,d[n][i]);
64         if(res==INF) printf("Case %d: %d\n",++t,-1);
65         else printf("Case %d: %d\n",++t,res);
66     }
67     return 0;
68 }

 

HDU2457 DNA repair(AC自动机+DP)

标签:

原文地址:http://www.cnblogs.com/WABoss/p/5170026.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!