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

    DNA repair
    Time Limit: 2000MS Memory Limit: 65536KB 64bit IO Format: %I64d & %I64u

    Description

    Biologists finally invent techniques of repairing DNA that contains segments causing kinds of inherited diseases. For the sake of simplicity, a DNA is represented as a string containing characters 'A', 'G' , 'C' and 'T'. The repairing techniques are simply to change some characters to eliminate all segments causing diseases. For example, we can repair a DNA "AAGCAG" to "AGGCAC" to eliminate the initial causing disease segments "AAG", "AGC" and "CAG" by changing two characters. Note that the repaired DNA can still contain only characters 'A', 'G', 'C' and 'T'.

    You are to help the biologists to repair a DNA by changing least number of characters.

    Input

    The input consists of multiple test cases. Each test case starts with a line containing one integers N (1 ≤ N ≤ 50), which is the number of DNA segments causing inherited diseases. 
    The following N lines gives N non-empty strings of length not greater than 20 containing only characters in "AGCT", which are the DNA segments causing inherited disease. 
    The last line of the test case is a non-empty string of length not greater than 1000 containing only characters in "AGCT", which is the DNA to be repaired.

    The last test case is followed by a line containing one zeros.

    Output

    For each test case, print a line containing the test case number( beginning with 1) followed by the 
    number of characters which need to be changed. If it's impossible to repair the given DNA, print -1.

    Sample Input

    2
    AAA
    AAG
    AAAG    
    2
    A
    TG
    TGAATG
    4
    A
    G
    C
    T
    AGT
    0

    Sample Output

    Case 1: 1
    Case 2: 4
    Case 3: -1
     
    【题意】
      已知一个DNA串和一些病毒DNA序列,求出最少改变DNA串中多少个字符,能使得串中不包含任意一个病毒序列。
     

    【分析】

      建AC自动机然后DP,不要走到有标记的点即可。

     代码如下:

      1 #include<cstdio>
      2 #include<cstdlib>
      3 #include<cstring>
      4 #include<iostream>
      5 #include<algorithm>
      6 #include<queue>
      7 using namespace std;
      8 #define Maxn 3010
      9 #define Maxl 1010
     10 #define INF 0xfffffff
     11 
     12 int n;
     13 char s[20];
     14 char ss[Maxl];
     15 
     16 struct node
     17 {
     18     int cnt,fail;
     19     bool mark;
     20     int son[5];
     21 }t[Maxn];int tot;//=0;
     22 
     23 void upd(int x)
     24 {
     25     t[x].cnt=1;t[x].mark=0;
     26     memset(t[x].son,0,sizeof(t[x].son));
     27 }
     28 
     29 int mymin(int x,int y) {return x<y?x:y;}
     30 
     31 void read_trie()
     32 {
     33     scanf("%s",s+1);
     34     int len=strlen(s+1);
     35     int now=0;
     36     for(int i=1;i<=len;i++)
     37     {
     38         int ind=s[i]-'A'+1;
     39         if(ind==3) ind=2;
     40         else if(ind==7) ind=3;
     41         else if(ind==20) ind=4;
     42         if(!t[now].son[ind]) 
     43         {
     44             t[now].son[ind]=++tot;
     45             upd(tot);
     46         }
     47         now=t[now].son[ind];
     48         if(i==len) t[now].mark=1;
     49     }
     50 }
     51 
     52 queue<int > q;
     53 // bool inq[Maxn];
     54 void build_AC()
     55 {
     56     while(!q.empty()) q.pop();
     57     q.push(0);//inq[0]=1;
     58     while(!q.empty())
     59     {
     60         int x=q.front();q.pop();
     61         for(int i=1;i<=4;i++) 
     62         {
     63             if(t[x].son[i])
     64             {
     65                 t[t[x].son[i]].fail=x?t[t[x].fail].son[i]:0;
     66                 q.push(t[x].son[i]);
     67             }
     68             else t[x].son[i]=t[t[x].fail].son[i];
     69             if(t[t[x].fail].mark) t[x].mark=1;
     70         }
     71     }
     72 }
     73 
     74 int f[Maxn][Maxl];
     75 void dp()
     76 {
     77     scanf("%s",ss+1);
     78     int len=strlen(ss+1);
     79     for(int i=1;i<=len;i++)
     80     {
     81         if(ss[i]=='C') ss[i]='B';
     82         else if(ss[i]=='G') ss[i]='C';
     83         else if(ss[i]=='T') ss[i]='D';
     84     }
     85     memset(f,63,sizeof(f));
     86     f[0][0]=0;
     87     for(int i=1;i<=len;i++)
     88      for(int j=0;j<=tot;j++) if(f[i-1][j]<INF)
     89      {
     90          for(int k=1;k<=4;k++) if(!t[t[j].son[k]].mark)
     91          {
     92              if(ss[i]-'A'+1==k) 
     93               f[i][t[j].son[k]]=mymin(f[i][t[j].son[k]],f[i-1][j]);
     94              else f[i][t[j].son[k]]=mymin(f[i][t[j].son[k]],f[i-1][j]+1);
     95          }
     96      }
     97     int ans=INF;
     98     for(int i=0;i<=tot;i++) ans=mymin(f[len][i],ans);
     99     if(ans<=len) printf("%d
    ",ans);
    100     else printf("-1
    ");
    101 }
    102 
    103 void init()
    104 {
    105     tot=0;
    106     upd(0);
    107     for(int i=1;i<=n;i++)
    108     {
    109         read_trie();
    110     }
    111     build_AC();
    112 }
    113 
    114 int main()
    115 {
    116     int kase=0;
    117     while(1)
    118     {
    119         scanf("%d",&n);
    120         if(n==0) break;
    121         init();
    122         printf("Case %d: ",++kase);
    123         dp();
    124     }
    125     return 0;
    126 }
    [POJ3691]

    2016-07-11 10:06:17

     

  • 相关阅读:
    js绑定事件方法:addEventListener的兼容问题
    jQuery中$(function(){})与(function($){})(jQuery)、$(document).ready(function(){})等的区别讲解
    jQuery事件绑定函数:on()与bind()的差别
    click事件的累加绑定
    HTML标签marquee实现滚动效果
    原生js添加类名,删除类名
    CSS相邻兄弟选择器
    视差滚动
    纯js实现分页
    下拉加载更多内容(滚动加载)
  • 原文地址:https://www.cnblogs.com/Konjakmoyu/p/5659327.html
Copyright © 2011-2022 走看看