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 }
  • 相关阅读:
    深入浅出讲解 ElasticSearch的安装与使用【建议收藏】
    win10 elasticsearch安装IK中文分词器
    elasticsearch 使用过程中经常遇到的问题
    在给elasticsearch安装head插件时,npm install 版本不匹配
    elasticsearch.bat闪退的解决方案
    图文详解| Node.js安装及环境配置之Windows篇
    面试必备:秒杀场景九个细节
    vagrant 安装中遇到的问题
    2021 年上海市成人高校考试招生工作规定
    成考专科数学模拟试题一及答案
  • 原文地址:https://www.cnblogs.com/WABoss/p/5170026.html
Copyright © 2011-2022 走看看