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

    题目连接:hdu_2457_DNA repair

    题意:

    给你N个字符串,最后再给你一个要匹配的串,问你最少修改多少次,使得这个串不出现之前给的N的字符串

    题解:

    刚学AC自动机,切这题还真不知道怎么来DP,然后看了一下题解,需要在失败指针那里做文章,这里我们要将trie的每一个节点当作一个状态,然后设dp[i][j]表示考虑到第i个字符,j这个trie节点时的最小修改次数,为什么要这样考虑,因为AC自动机在匹配失败的时候会转向其他的节点,所以这里我们要考虑每一个节点的状态,然后当前节点的子节点如果不存在也要处理一下,就指向这个节点的fail指针,这样我们在后面dp的时候才能保证匹配失败的时候回到fail节点

     1 #include<cstdio>
     2 #include<cstring>
     3 #define F(i,a,b) for(int i=a;i<=b;i++)
     4 
     5 inline void up(int &x,int y){if(x>y)x=y;}
     6 const int AC_N=1011,inf=1e8;
     7 struct AC_automation{
     8     int tr[AC_N][4],cnt[AC_N],Q[AC_N],fail[AC_N],tot;
     9     int gt(char x){
    10         if(x=='A')return 0;
    11         if(x=='G')return 1;
    12         if(x=='C')return 2;
    13         if(x=='T')return 3;
    14     }
    15     void nw(){cnt[++tot]=0;memset(tr[tot],-1,sizeof(tr[tot]));}
    16     void init(){tot=-1,fail[0]=-1,nw();}
    17     void insert(char *s,int x=0){
    18         for(int len=strlen(s),i=0,w;i<len;x=tr[x][w],i++)
    19             if(tr[x][w=gt(s[i])]==-1)nw(),tr[x][w]=tot;
    20         cnt[x]=1;//串尾标记
    21     }
    22     void build(int head=1,int tail=0){
    23         for(Q[++tail]=0;head<=tail;){
    24             for(int i=0,x=Q[head++],p=-1;i<=3;i++)if(~tr[x][i]){
    25                 if(x==0)fail[tr[0][i]]=0;
    26                 else{
    27                     for(p=fail[x],fail[tr[x][i]]=0;~p;p=fail[p])
    28                     if(~tr[p][i]){fail[tr[x][i]]=tr[p][i];break;}
    29                 }//如果他失败指针指向的节点的子节点为危险DNA那么这点的子节点也不能取
    30                 if(cnt[fail[tr[x][i]]])cnt[tr[x][i]]=1;
    31                 Q[++tail]=tr[x][i];
    32             }else if(x==0)tr[0][i]=0;//不存在的节点指向失败指针的位置
    33             else tr[x][i]=tr[fail[x]][i];
    34         }
    35     }
    36     int dp[1010][1010];
    37     int ask(char *s){
    38         int len=strlen(s),ans=inf;
    39         F(i,0,len)F(j,0,tot)dp[i][j]=inf;
    40         dp[0][0]=0;
    41         F(i,1,len)F(j,0,tot){
    42             if(cnt[j]||dp[i-1][j]==inf)continue;
    43             F(k,0,3){
    44                 int nxt=tr[j][k];
    45                 if(cnt[nxt])continue;
    46                 up(dp[i][nxt],dp[i-1][j]+(gt(s[i-1])!=k));
    47             }
    48         }
    49         F(i,0,tot)up(ans,dp[len][i]);
    50         return ans==inf?-1:ans;
    51     }
    52 }AC;
    53 
    54 char buf[1010];
    55 int main(){
    56     int n,ic=1;
    57     while(~scanf("%d",&n),n){
    58         AC.init();
    59         F(i,1,n)scanf("%s",buf),AC.insert(buf);
    60         AC.build();
    61         scanf("%s",buf);
    62         printf("Case %d: %d
    ",ic++,AC.ask(buf));
    63     }
    64     return 0;
    65 }
    View Code
  • 相关阅读:
    mysql学习【第4篇】:数据库之数据类型
    mysql学习【第3篇】:数据库之增删改查操作
    mysql学习【第2篇】:基本操作和存储引擎
    mysql学习【第1篇】:数据库安装
    模块
    面向对象 之 反射 内置方法
    面向对象 的属性 类方法 静态方法
    python day
    day 18 面向对象的 继承
    python day
  • 原文地址:https://www.cnblogs.com/bin-gege/p/5696083.html
Copyright © 2011-2022 走看看