zoukankan      html  css  js  c++  java
  • poj3691 DNA repair[DP+AC自动机]

    $给定 n 个模式串,和一个长度为 m 的原串 s,求至少修改原串中的几个字符可以使得原串中不包含任一个模式串。模式串总长度 ≤ 1000,m ≤ 1000。$


    先建出模式串的AC自动机,然后考虑怎么求最优解。考虑AC自动机上DP,设$f_{i,j}$走了$i$步之后在$j$节点时候的最少修改次数。

    标记处所有不能走到的点(即走到就匹配了的点,即后缀为某一模式串的所有点),走点的时候应当回避这些点,转移的时候向合法的状态转移,分两种。

    一种沿着原串$s_i$走,$f_{i+1,to_j}leftarrow f_{i,j}$,另一种是走其他路,$f_{i+1,to_j'}leftarrow f_{i,j}+1$。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<cmath>
     6 #include<queue>
     7 #define dbg(x) cerr << #x << " = " << x <<endl
     8 using namespace std;
     9 typedef long long ll;
    10 typedef double db;
    11 typedef pair<int,int> pii;
    12 template<typename T>inline T _min(T A,T B){return A<B?A:B;}
    13 template<typename T>inline T _max(T A,T B){return A>B?A:B;}
    14 template<typename T>inline char MIN(T&A,T B){return A>B?(A=B,1):0;}
    15 template<typename T>inline char MAX(T&A,T B){return A<B?(A=B,1):0;}
    16 template<typename T>inline void _swap(T&A,T&B){A^=B^=A^=B;}
    17 template<typename T>inline T read(T&x){
    18     x=0;int f=0;char c;while(!isdigit(c=getchar()))if(c=='-')f=1;
    19     while(isdigit(c))x=x*10+(c&15),c=getchar();return f?x=-x:x;
    20 }
    21 const int N=1000+7,INF=0x3f3f3f3f;
    22 int ha[128],tr[N][4],ban[N],nxt[N],legal[N],cnt,tot;
    23 char s[N];
    24 int n;
    25 inline void Insert(){
    26     int len=strlen(s+1),x=0;
    27     for(register int i=1,c=ha[s[1]];i<=len;++i,c=ha[s[i]]){
    28         if(!tr[x][c])tr[x][c]=++tot;
    29         x=tr[x][c];
    30     }
    31     ban[x]=1;
    32 }
    33 queue<int> q;
    34 inline void Build(){
    35     legal[cnt=1]=0;
    36     memset(nxt,0,sizeof nxt);
    37     for(register int i=0;i<4;++i)if(tr[0][i])nxt[tr[0][i]]=0,q.push(tr[0][i]);
    38     while(!q.empty()){
    39         int x=q.front();q.pop();
    40         if(ban[nxt[x]])ban[x]=1;
    41         if(!ban[x])legal[++cnt]=x;
    42         for(register int i=0;i<4;++i)
    43             if(tr[x][i])nxt[tr[x][i]]=tr[nxt[x]][i],q.push(tr[x][i]);
    44             else tr[x][i]=tr[nxt[x]][i];
    45     }
    46 }
    47 #define j legal[_]
    48 int f[N][N],ans,T;
    49 inline void dp(){
    50     memset(f,0x3f,sizeof f);
    51     f[0][0]=0;ans=INF;
    52     int len=strlen(s+1);
    53     for(register int i=0;i<len;++i)
    54         for(register int _=1;_<=cnt;++_)if(f[i][j]<INF){
    55             int c=ha[s[i+1]];//dbg(i),dbg(j),dbg(f[i][j]);
    56             for(register int k=0;k<4;++k)
    57                 if(!ban[tr[j][k]]&&(c^k))
    58                     MIN(f[i+1][tr[j][k]],f[i][j]+1);
    59             if(!ban[tr[j][c]])MIN(f[i+1][tr[j][c]],f[i][j]);
    60         }
    61     for(register int _=1;_<=cnt;++_)MIN(ans,f[len][j]);
    62 }
    63 #undef j
    64 int main(){//freopen("test.in","r",stdin);//freopen("test.ans","w",stdout);
    65     ha['A']=0,ha['C']=1,ha['G']=2,ha['T']=3;
    66     while(read(n)){
    67         memset(ban,0,sizeof ban);memset(tr,0,sizeof tr),tot=0;
    68         for(register int i=1;i<=n;++i)scanf("%s",s+1),Insert();
    69         Build();scanf("%s",s+1);dp();
    70         printf("Case %d: %d
    ",++T,ans<INF?ans:-1);
    71     }
    72     return 0;
    73 }
    View Code

    总结:AC自动机上DP多为$f_{i,j}$型状态设计,需要考虑每一步各种转移情况。过于浅薄

  • 相关阅读:
    数据库自动备份(转)
    sqlserver常用全局变量
    Remoting通讯实例
    自定义ORM框架(转转)
    带格式导出数据到Excel
    app.config动态修改及读取
    学习笔记之AJAX无刷新分页
    游标(转转)
    Sql Server索引(转载)
    流Stream个人学习理解
  • 原文地址:https://www.cnblogs.com/saigyouji-yuyuko/p/11558737.html
Copyright © 2011-2022 走看看