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

    题目链接

    能AC还是很开心的...此题没有POJ2778那么难,那个题还需要矩阵乘法,两个题有点相似的。

    做题之前,把2778代码重新看了一下,回忆一下当时做题的思路,回忆AC自动机是干嘛的...

    状态表示dp[i][j]长度为i的以j串为结束的最小改变数目。AC自动机预处理一下,然后DP。

    卡内存+不知道状态数,MLE+RE+WA了多次。

      1 #include <iostream>
      2 #include <cstring>
      3 #include <cstdio>
      4 #include <queue>
      5 #include <algorithm>
      6 #include <cstdlib>
      7 using namespace std;
      8 #define N 2222222
      9 #define INF 10000000
     10 int trie[N][4];
     11 int o[N];
     12 int que[N];
     13 int fail[N];
     14 int dp[1001][1001];
     15 int t;
     16 void CL()
     17 {
     18     memset(trie,-1,sizeof(trie));
     19     memset(o,0,sizeof(o));
     20     t = 1;
     21 }
     22 int judge(char s)
     23 {
     24     switch(s)
     25     {
     26         case'A':return 0;
     27         case'C':return 1;
     28         case'G':return 2;
     29         case'T':return 3;
     30     }
     31     return 0;
     32 }
     33 void insert(char *str)
     34 {
     35     int i,len,root;
     36     root = 0;
     37     len = strlen(str);
     38     for(i = 0;i < len;i ++)
     39     {
     40         if(trie[root][judge(str[i])] == -1)
     41         trie[root][judge(str[i])] = t ++;
     42         root = trie[root][judge(str[i])];
     43     }
     44     o[root] = 1;
     45 }
     46 void build_ac()
     47 {
     48     int head,tail,front,i;
     49     head = tail = 0;
     50     for(i = 0;i < 4;i ++)
     51     {
     52         if(trie[0][i] != -1)
     53         {
     54             fail[trie[0][i]] = 0;
     55             que[tail++] = trie[0][i];
     56         }
     57         else
     58         {
     59             trie[0][i] = 0;
     60         }
     61     }
     62     while(head != tail)
     63     {
     64         front = que[head++];
     65         if(o[fail[front]])
     66         o[front] = 1;
     67         for(i = 0;i < 4;i ++)
     68         {
     69             if(trie[front][i] != -1)
     70             {
     71                 que[tail++] = trie[front][i];
     72                 fail[trie[front][i]] = trie[fail[front]][i];
     73             }
     74             else
     75             {
     76                 trie[front][i] = trie[fail[front]][i];
     77             }
     78         }
     79     }
     80 }
     81 int main()
     82 {
     83     int n,i,j,k,len,flag,cas = 1;
     84     char str[2001];
     85     while(scanf("%d",&n)!=EOF)
     86     {
     87         if(n == 0) break;
     88         CL();
     89         for(i = 1;i <= n;i ++)
     90         {
     91             scanf("%s",str);
     92             insert(str);
     93         }
     94         build_ac();
     95         scanf("%s",str);
     96         len = strlen(str);
     97         for(i = 0;i <= len;i ++)
     98         {
     99             for(j = 0;j <= t;j ++)
    100             dp[i][j] = INF;
    101         }
    102         dp[0][0] = 0;
    103         for(i = 0;i < len;i ++)
    104         {
    105             for(j = 0;j < t;j ++)
    106             {
    107                 if(o[j]) continue;
    108                 for(k = 0;k < 4;k ++)
    109                 {
    110                     if(o[trie[j][k]]) continue;
    111                     flag = !(k == judge(str[i]));
    112                     dp[i+1][trie[j][k]] = min(dp[i+1][trie[j][k]],dp[i][j] + flag);
    113                 }
    114             }
    115         }
    116         int ans = INF;
    117         for(i = 0;i < t;i ++)
    118         {
    119             ans = min(ans,dp[len][i]);
    120         }
    121         printf("Case %d: ",cas ++);
    122         if(ans == INF)
    123         printf("-1
    ");
    124         else
    125         printf("%d
    ",ans);
    126     }
    127     return 0;
    128 }
  • 相关阅读:
    Java中的多线程
    Service组件
    Notification和Notification Manager的使用
    Java网络编程
    Intent组件
    Android 多任务多线程断点下载
    hdu 2045
    hdu 2492
    poj 2785
    湖南省第六届程序设计大赛D(台球碰撞)
  • 原文地址:https://www.cnblogs.com/naix-x/p/3221065.html
Copyright © 2011-2022 走看看