zoukankan      html  css  js  c++  java
  • HDU2457 DNA repair(AC自动机+DP)

    题目一串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],flag[ch[x][i]]|=flag[ch[fail[x]][i]];
    27             else ch[x][i]=ch[fail[x]][i];
    28         }
    29     }
    30 }
    31 int d[1111][1111];
    32 int main(){
    33     idx['A']=0; idx['G']=1; idx['C']=2; idx['T']=3;
    34     char str[1111];
    35     int n,t=0;
    36     while(~scanf("%d",&n) && n){
    37         tn=0;
    38         memset(ch,0,sizeof(ch));
    39         memset(flag,0,sizeof(flag));
    40         while(n--){
    41             scanf("%s",str);
    42             insert(str);
    43         }
    44         init();
    45         scanf("%s",str+1);
    46         n=strlen(str+1);
    47         for(int i=0; i<=n; ++i){
    48             for(int j=0; j<=tn; ++j) d[i][j]=INF;
    49         }
    50         d[0][0]=0;
    51         for(int i=0; i<n; ++i){
    52             for(int j=0; j<=tn; ++j){
    53                 if(d[i][j]==INF || flag[j]) continue;
    54                 for(int k=0; k<4; ++k){
    55                     if(flag[ch[j][k]]) continue;
    56                     if(idx[str[i+1]]==k) d[i+1][ch[j][k]]=min(d[i+1][ch[j][k]],d[i][j]);
    57                     else d[i+1][ch[j][k]]=min(d[i+1][ch[j][k]],d[i][j]+1);
    58                 }
    59             }
    60         }
    61         int res=INF;
    62         for(int i=0; i<=tn; ++i) res=min(res,d[n][i]);
    63         if(res==INF) printf("Case %d: %d
    ",++t,-1);
    64         else printf("Case %d: %d
    ",++t,res);
    65     }
    66     return 0;
    67 }
  • 相关阅读:
    C++实现高斯滤波器
    移动通信
    最简单的DLL
    C/C++ 编译和链接过程
    Servlet 详解
    对 Java 集合的巧妙利用
    Java 泛型
    Java 字符编码与解码
    HTTP 400 错误
    a 标签的四种样式
  • 原文地址:https://www.cnblogs.com/WABoss/p/5170026.html
Copyright © 2011-2022 走看看