zoukankan      html  css  js  c++  java
  • POJ 3691 TRIE图+DP

    题意:

    已知一个DNA串和一些病毒DNA序列,求出最少改变DNA串中多少个字符,能使得串中不包含任意一个病毒序列。

    题解:

    嗯,和上一个trie图一样,把病毒建成trie,只要母串不能再trie上走到危险节点即可(危险节点就是病毒dna序列的终止的那个被标有fg的节点)。

    然后trie图上的dp,要走到危险节点的时候,枚举转移即可。

    View Code
     1 #include <iostream>
     2 #include <cstring>
     3 #include <cstdio>
     4 #include <cstdlib>
     5 #include <algorithm>
     6 
     7 #define M 1111
     8 #define N 111
     9 #define INF 0x3f3f3f3f
    10 
    11 using namespace std;
    12 
    13 struct TR
    14 {
    15     int son[4]; int f; bool fg;
    16 }tr[N*N];
    17 
    18 int map[N],cnt,q[N*N],n,m,cas;
    19 char str[N],a[M];
    20 int dp[M][N*N];
    21 
    22 inline void insert(char *s)
    23 {
    24     int len=strlen(s+1);
    25     int now=1;
    26     for(int i=1;i<=len;i++)
    27     {
    28         if(!tr[now].son[map[s[i]]]) tr[now].son[map[s[i]]]=++cnt;
    29         now=tr[now].son[map[s[i]]];
    30     }
    31     tr[now].fg=true;
    32 }
    33 
    34 inline void build()
    35 {
    36     int h=1,t=2,sta,now,tmp;
    37     q[1]=1;
    38     while(h<t)
    39     {
    40         sta=q[h++];
    41         for(int i=0;i<4;i++)
    42         {
    43             now=tr[sta].son[i];
    44             if(sta==1) tmp=1;
    45             else tmp=tr[tr[sta].f].son[i];
    46             if(now==0) tr[sta].son[i]=tmp;
    47             else
    48             {
    49                 tr[now].f=tmp; tr[now].fg|=tr[tmp].fg;
    50                 q[t++]=now;
    51             }
    52         }
    53     }
    54 }
    55 
    56 inline void read()
    57 {
    58     memset(tr,0,sizeof tr);
    59     tr[cnt=1].f=1;
    60     for(int i=1;i<=n;i++)
    61     {
    62         scanf("%s",str+1);
    63         insert(str);
    64     }
    65     scanf("%s",a+1);
    66     m=strlen(a+1);
    67     build();
    68 }
    69 
    70 inline void go()
    71 {
    72     memset(dp,0x3f,sizeof dp);
    73     dp[0][1]=0;
    74     for(int i=0;i<m;i++)
    75         for(int j=1;j<=cnt;j++)
    76         {
    77             for(int k=0;k<4;k++)
    78                 if(!tr[tr[j].son[k]].fg) dp[i+1][tr[j].son[k]]=min(dp[i+1][tr[j].son[k]],dp[i][j]+1);
    79             if(!tr[tr[j].son[map[a[i+1]]]].fg) dp[i+1][tr[j].son[map[a[i+1]]]]=min(dp[i+1][tr[j].son[map[a[i+1]]]],dp[i][j]);
    80         }
    81     int ans=INF;
    82     for(int i=1;i<=cnt;i++) ans=min(ans,dp[m][i]);
    83     if(ans==INF) ans=-1;
    84     printf("Case %d: %d\n",++cas,ans);
    85 }
    86 
    87 int main()
    88 {
    89     map['A']=0; map['G']=1; map['C']=2; map['T']=3;
    90     while(scanf("%d",&n),n) read(),go();
    91     return 0;
    92 }
  • 相关阅读:
    积水路面Wet Road Materials 2.3
    门控时钟问题
    饮料机问题
    Codeforces Round #340 (Div. 2) E. XOR and Favorite Number (莫队)
    Educational Codeforces Round 82 (Rated for Div. 2)部分题解
    Educational Codeforces Round 86 (Rated for Div. 2)部分题解
    Grakn Forces 2020部分题解
    2020 年百度之星·程序设计大赛
    POJ Nearest Common Ancestors (RMQ+树上dfs序求LCA)
    算法竞赛进阶指南 聚会 (LCA)
  • 原文地址:https://www.cnblogs.com/proverbs/p/2945092.html
Copyright © 2011-2022 走看看