dyllalala

导航

[poj 3691]DNA repair

好久没刷 poj 了,今天练习 AC 自动机时去水了一发喵~

在 poj 上 A 题的感觉并没有 BZOJ 上那么愉悦,准确的说是痛不欲生

真是应了那句老话,你再慢也有比你慢的,你再快也有比你快的……

跪求那些 0ms 的代码啊,还有那么多人都只跑了 32ms 啊!!

果然还是我太弱了吗?一定是我还太弱了 TAT 

 

一道裸裸的 AC 自动机上 dp 

令 dp[i][j] 表示母串的前 i 个字母遍历 AC 自动机,使之到达 j 节点,至少要修改多少个字母

dp[i+1][k]=min(dp[i+1][k], dp[i][j]+CHAR(j->k)!=s[i])  { k 不为匹配点}

CHAR(j->k) 是指在 AC 自动机上从点 j 转移到点 k 的边时经过的字母

答案就是 min{dp[len(s)][i]} 了喵~

 

我才不会说我是来晒我的 AC 自动机代码的呢~  (虽然被 poj 的各大神犇搞得一点优越感都没有……)

 

  1 #include <cstdio>
  2 #include <cstring>
  3 const int inf=0x3F3F3F3F;
  4 const int sizeOfText=1024;
  5 const int sizeOfType=4;
  6 const int sizeOfMemory=1024;
  7 
  8 namespace trieDfa
  9 {
 10     struct node
 11     {
 12         int idx;
 13         bool end;
 14         node * fail;
 15         node * ch[sizeOfType];
 16     };
 17     node * dfa;
 18     node memory[sizeOfMemory]; int port;
 19     node * E[sizeOfMemory];
 20     inline node * newnode()
 21     {
 22         node * ret=memory+port;
 23         E[ret->idx=port++]=ret;
 24         ret->end=0;
 25         ret->fail=NULL;
 26         memset(ret->ch, 0, sizeof(ret->ch));
 27         return ret;
 28     }
 29     inline void clear() {port=0; dfa=newnode();}
 30 
 31     inline int ord(char ch)
 32     {
 33         switch (ch)
 34         {
 35             case 'A':return 0;
 36             case 'G':return 1;
 37             case 'C':return 2;
 38             case 'T':return 3;
 39         }
 40     }
 41     inline void insert(char * s)
 42     {
 43         int len=strlen(s);
 44         node * t=dfa;
 45         for (int i=0;i<len;i++)
 46         {
 47             if (!t->ch[ord(s[i])]) t->ch[ord(s[i])]=newnode();
 48             t=t->ch[ord(s[i])];
 49         }
 50         t->end=1;
 51     }
 52     inline void buildDfa()
 53     {
 54         static node * queue[sizeOfMemory];
 55         int l=0, r=0;
 56 
 57         dfa->fail=dfa;
 58         for (int i=0;i<sizeOfType;i++)
 59             if (!dfa->ch[i]) dfa->ch[i]=dfa;
 60             else dfa->ch[i]->fail=dfa, queue[r++]=dfa->ch[i];
 61 
 62         for ( ;l<r; )
 63         {
 64             node * u=queue[l++];
 65             u->end|=u->fail->end;
 66             for (int i=0;i<sizeOfType;i++)
 67                 if (u->ch[i])
 68                 {
 69                     u->ch[i]->fail=u->fail->ch[i];
 70                     queue[r++]=u->ch[i];
 71                 }
 72                 else
 73                     u->ch[i]=u->fail->ch[i];
 74         }
 75     }
 76 }
 77 using namespace trieDfa;
 78 
 79 int cases, n;
 80 char str[sizeOfText];
 81 int f[sizeOfText][sizeOfMemory];
 82 inline int min(int x, int y) {return x<y?x:y;}
 83 inline int dp(char * );
 84 
 85 int main()
 86 {
 87     for (scanf("%d", &n);n;scanf("%d", &n))
 88     {
 89         clear();
 90         for (int i=1;i<=n;i++)
 91         {
 92             scanf("%s", str);
 93             insert(str);
 94         }
 95         buildDfa();
 96         scanf("%s", str);
 97         printf("Case %d: %d\n", ++cases, dp(str));
 98     }
 99 
100     return 0;
101 }
102 inline int dp(char * s)
103 {
104     int len=strlen(s);
105     int ret=inf;
106 
107     memset(f, inf, sizeof(f));
108     f[0][0]=0;    
109     for (int i=0;i<len;i++)
110         for (int j=0;j<port;j++)
111             for (int k=0;k<sizeOfType;k++)
112                 if (!E[j]->ch[k]->end)
113                     f[i+1][E[j]->ch[k]->idx]=min(f[i+1][E[j]->ch[k]->idx], f[i][j]+(ord(s[i])!=k));
114     for (int i=0;i<port;i++) ret=min(ret, f[len][i]);    
115 
116     return ret==inf?-1:ret;
117 }
本傻装B系列

 

posted on 2014-08-11 18:14  dyllalala  阅读(237)  评论(0编辑  收藏  举报