• 【poj3691-DNA repair】AC自动机+DP


    题意:给n个病毒DNA序列,再给一个DNA序列,问该序列至少修改多少个碱基能不含任何病毒DNA。病毒DNA序列一共不超过1000,询问的DNA长度不超过1000。

    题解:DP:d[l][p]表示询问到第l位、当前在AC自动机上的位置为p时的最少修改数,用d[l][p]推d[l+1][x]。本来打的是递归,结果递归死循环了。。于是改成递推了。

    不想清楚的话递归真的好容易死掉TAT

      1 //poj3691
      2 #include<cstdio>
      3 #include<cstdlib>
      4 #include<cstring>
      5 #include<iostream>
      6 #include<queue>
      7 using namespace std;
      8 
      9 const int N=1100,INF=(int)1e9;
     10 int n,num,sl,ans,d[N][N];
     11 char s[N];
     12 struct node{
     13     int fail,fa,bk,son[5];
     14 }a[N];
     15 queue<int> q;
     16 
     17 int minn(int x,int y){return x<y ? x:y;}
     18 
     19 int idx(char c)
     20 {
     21     if(c=='A') return 1;
     22     if(c=='T') return 2;
     23     if(c=='C') return 3;
     24     if(c=='G') return 4;
     25 }
     26 
     27 void clear(int x)
     28 {
     29     a[x].bk=a[x].fail=a[x].fa=0;
     30     memset(a[x].son,0,sizeof(a[x].son));
     31 }
     32 
     33 void read_trie()
     34 {
     35     scanf("%s",s);
     36     int x=0,l=strlen(s);
     37     for(int i=0;i<l;i++)
     38     {
     39         int ind=idx(s[i]);
     40         if(!a[x].son[ind])
     41         {
     42             clear(++num);
     43             a[x].son[ind]=num;
     44             a[num].fa=x;
     45         }
     46         x=a[x].son[ind];
     47     }
     48     a[x].bk=1;
     49 }
     50 
     51 void buildAC()
     52 {
     53     while(!q.empty()) q.pop();
     54     for(int i=1;i<=4;i++)
     55         if(a[0].son[i]) q.push(a[0].son[i]);
     56     while(!q.empty())
     57     {
     58         int x=q.front();q.pop();
     59         int fail=a[x].fail;
     60         for(int i=1;i<=4;i++)
     61         {
     62             if(a[x].son[i])
     63             {
     64                 int y=a[x].son[i],z=a[fail].son[i];
     65                 a[y].fail=z;
     66                 a[y].bk|=a[z].bk;
     67                 q.push(y);
     68             }
     69             else a[x].son[i]=a[fail].son[i];
     70         }
     71     }
     72 }
     73 
     74 int main()
     75 {
     76     freopen("a.in","r",stdin);
     77     freopen("a.out","w",stdout);
     78     int T=0;
     79     while(1)
     80     {
     81         scanf("%d",&n);
     82         if(!n) return 0;
     83         num=0;
     84         clear(0);
     85         for(int i=1;i<=n;i++) read_trie();
     86         buildAC();
     87         scanf("%s",s+1);
     88         sl=strlen(s+1);
     89         ans=INF;
     90         memset(d,63,sizeof(d));
     91         d[0][0]=0;
     92         for(int i=0;i<sl;i++)
     93         {
     94             for(int j=0;j<=num;j++)//在AC自动机上的位置
     95             {
     96                 if(d[i][j]<INF)
     97                 {
     98                     int ind=idx(s[i+1]);
     99                     int x=a[j].son[ind];
    100                     for(int k=1;k<=4;k++)
    101                     {
    102                         int y=a[j].son[k];
    103                         if(a[y].bk || x==y) continue;
    104                         d[i+1][y]=minn(d[i+1][y],d[i][j]+1);
    105                     }
    106                     if(a[x].bk==0) 
    107                         d[i+1][x]=minn(d[i+1][x],d[i][j]);
    108                 }
    109             }
    110         }
    111         for(int i=0;i<=num;i++) ans=minn(ans,d[sl][i]);
    112         if(ans<INF) printf("Case %d: %d
    ",++T,ans);
    113         else printf("Case %d: -1
    ",++T);
    114     }
    115     return 0;
    116 }
  • 相关阅读:
    Feed back TFS 2017 RC upgrade status to product team in product group 2017.03.01
    TFS Training for Kunlun bank (http://www.klb.cn/) 微软研发流程(ALM)管理培训会议(昆仑银行) 2016.09.21
    微软DevOps软件开发高级培训课程(深圳站) 2016.04.06
    秒杀系统架构设计
    程序员职业规划
    程序员跳槽时,会遇到哪些套路?
    程序员3大点
    程序员37个小贴士
    程序员6大点
    程序员面试 10 大潜规则
  • 原文地址:https://www.cnblogs.com/KonjakJuruo/p/5680435.html
Copyright © 2020-2023  润新知