• HDU 2457 DNA repair (AC自动机+DP)


    题意:给N个串,一个大串,要求在最小的改变代价下,得到一个不含上述n个串的大串。

    思路:dp,f[i][j]代表大串中第i位,AC自动机上第j位的最小代价。

     1 #include<algorithm>
     2 #include<cstdio>
     3 #include<cmath>
     4 #include<cstring>
     5 #include<iostream>
     6 #include<queue>
     7 std::queue<int>Q;
     8 int ch[10005][5],end[10005],f[1005][1005],sz,root,fail[100005],n,Tcase;
     9 char s[10005];
    10 int newnode(){
    11     for (int i=0;i<=3;i++) 
    12      ch[sz][i]=-1;
    13     end[sz]=0;
    14     sz++; 
    15     return sz-1;
    16 }
    17 void clear(){
    18     sz=0;root=newnode();
    19 }
    20 int num(char c){
    21     if (c=='A') return 0;
    22     else
    23     if (c=='T') return 1;
    24     else
    25     if (c=='G') return 2;
    26     else
    27     if (c=='C') return 3;
    28     return 0;
    29 }
    30 void insert(){
    31     scanf("%s",s);
    32     int len=strlen(s);
    33     int now=root;
    34     for (int i=0;i<len;i++){
    35         if (ch[now][num(s[i])]==-1) ch[now][num(s[i])]=newnode();
    36         now=ch[now][num(s[i])];
    37     }
    38     end[now]=1;
    39 }
    40 void build(){
    41     int now=root;
    42     std::queue<int>Q;
    43     fail[root]=root;
    44     for (int i=0;i<=3;i++) 
    45      if (ch[root][i]==-1) ch[root][i]=root;
    46      else fail[ch[root][i]]=root,Q.push(ch[root][i]);
    47     while (!Q.empty()){
    48         int now=Q.front();Q.pop();
    49         if (end[fail[now]]==1) end[now]|=1;
    50         for (int i=0;i<=3;i++){
    51             if (ch[now][i]==-1) ch[now][i]=ch[fail[now]][i];
    52             else fail[ch[now][i]]=ch[fail[now]][i],Q.push(ch[now][i]);
    53         }
    54     } 
    55 }
    56 void dp(){
    57     scanf("%s",s);
    58     int len=strlen(s);
    59     for (int i=0;i<=len;i++)
    60      for (int j=0;j<=sz;j++)
    61       f[i][j]=99999999;
    62     f[0][root]=0;
    63     for (int i=0;i<len;i++)
    64      for (int j=0;j<sz;j++)
    65       if (f[i][j]<99999999){
    66             for (int k=0;k<=3;k++){
    67                 int now=ch[j][k];
    68                 if (end[now]) continue;
    69                 int tmp;
    70                 if (k==num(s[i])) tmp=f[i][j];
    71                 else tmp=f[i][j]+1;
    72                 f[i+1][now]=std::min(f[i+1][now],tmp);
    73             }
    74       }  
    75     int ans=99999999;
    76     for (int i=0;i<sz;i++)
    77      ans=std::min(ans,f[len][i]);
    78     if (ans==99999999) ans=-1;
    79     printf("%d
    ",ans);   
    80 }
    81 int main(){
    82     while (scanf("%d",&n)!=EOF){
    83         if (n==0) return 0;
    84         Tcase++;
    85         printf("Case %d: ",Tcase);
    86         clear();
    87         for (int i=1;i<=n;i++)
    88          insert();
    89         build();
    90         dp();
    91     }
    92 }
  • 相关阅读:
    西安.NET俱乐部群 推广代码
    跟我学Makefile(六)
    跟我学Makefile(五)
    跟我学Makefile(四)
    跟我学Makefile(三)
    跟我学Makefile(二)
    Kconfig文件说明2
    Kconfig文件说明
    kernel内核配置说明
    makefile中ifeq与ifneq dev/null和dev/zero简介 dd命令
  • 原文地址:https://www.cnblogs.com/qzqzgfy/p/5551731.html
Copyright © 2020-2023  润新知