poj 3769DNArepair
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了poj 3769DNArepair相关的知识,希望对你有一定的参考价值。
/*2016.01.22
*poj3769DNArepair.cpp
* ac自动机+dp, 多模式匹配
* 考虑存在这样的修改满足题意,则沿着修改后的字符串进行状态转移每一步都
* 将到达安全的状态(不含病毒串为子串),满足最优子结构。假设:
* c 为从状态from到to的字符,dp[i][to]表示第i步到达to状态最少需要改变的字符数,
* 状态from 和 to 都要是安全的:
* dp[i][to] = min(dp[i-1][from] + c != s[i], dp[i][to])
*/
1 #include <cstdio> 2 #include <map> 3 #include <string.h> 4 #include <algorithm> 5 using namespace std; 6 7 const int MAX = 1010, SZ = 4; 8 int dp[MAX], tmp[MAX], cur; 9 map<char, int> c2n; 10 11 class node { 12 public: 13 int unsafe; 14 node *next[SZ], *fail; 15 void init(){ 16 memset(this, 0, sizeof(node)); 17 } 18 }ac[MAX], *q[MAX], *rt; 19 20 void Insert(char *s){ 21 int i=0, idx; 22 node *p=rt; 23 for(i=0; s[i]; ++i){ 24 idx = c2n[s[i]]; 25 if(p->next[idx] == NULL){ 26 p->next[idx] = &ac[cur]; 27 ac[cur++].init(); 28 } 29 p = p->next[idx]; 30 } 31 p->unsafe = 1; 32 } 33 //v1: 34 // void BuildAC(){ 35 // int h = 1, t = 0, i; 36 // node *nd; 37 // q[0] = rt; 38 // rt->fail = NULL; 39 // while(t < h){ 40 // for(i=0; i<SZ; ++i){ 41 // if(q[t]->next[i] == NULL) continue; 42 // if(q[t] == rt) q[t]->next[i]->fail = rt; 43 // else { 44 // nd = q[t]->fail; 45 // while(nd != NULL && nd->next[i] == NULL) nd = nd->fail; 46 // if(nd == NULL) q[t]->next[i]->fail = rt; 47 // else { 48 // q[t]->next[i]->fail = nd->next[i]; 49 // q[t]->next[i]->unsafe |= nd->next[i]->unsafe; 50 // } 51 // } 52 // q[h++] = q[t]->next[i]; 53 // } 54 // ++t; 55 // } 56 // } 57 //v2: 58 void BuildAC(){ 59 int h=1, t=0, i; 60 node *nd; 61 q[0] = rt; 62 rt->fail = NULL; 63 while(t < h){ 64 for(i=0; i<SZ; ++i){ 65 if(q[t]->next[i] != NULL) q[h++] = q[t]->next[i]; 66 if(q[t] == rt){ 67 if(q[t]->next[i] == NULL) q[t]->next[i] = rt; 68 else q[t]->next[i]->fail = rt; 69 } 70 else { 71 nd = q[t]->fail; 72 if(q[t]->next[i] == NULL) q[t]->next[i] = nd->next[i]; 73 else { 74 q[t]->next[i]->fail = nd->next[i]; 75 q[t]->next[i]->unsafe |= nd->next[i]->unsafe; 76 } 77 } 78 } 79 ++t; 80 } 81 } 82 int Solve(char *s){ 83 int *bef = dp, *aft = tmp, i, j, k, n = strlen(s); 84 node *nd; 85 memset(bef, 0, sizeof(dp)); 86 for(i=0; i<n; ++i){ 87 memset(aft, 0x4, sizeof(dp)); 88 for(j=0; j<cur; ++j) 89 if(ac[j].unsafe == 0){ 90 for(k=0; k<SZ; ++k){ 91 int idx = ac[j].next[k] - rt; 92 // nd = &ac[j]; 93 // while(nd != rt && nd->next[k]==NULL) nd = nd->fail; 94 // if(nd->next[k] != NULL) idx = nd->next[k] - rt; 95 if(ac[idx].unsafe == 0){ 96 aft[idx] = min(aft[idx], bef[j]+(c2n[s[i]]!=k)); 97 } 98 } 99 //第一次动归从根出发 100 if(i == 0) break; 101 } 102 swap(aft, bef); 103 } 104 n = MAX; 105 for(i=0; i<cur; ++i) 106 if(ac[i].unsafe == 0) 107 n = min(n, bef[i]); 108 return n == MAX ? -1 : n; 109 } 110 111 int main() { 112 int i, n, t=0; 113 char s[MAX]; 114 rt = ac; 115 c2n[‘A‘] = 0; c2n[‘C‘] = 1; c2n[‘G‘] = 2; c2n[‘T‘] = 3; 116 while(scanf("%d", &n), n){ 117 cur = 1; 118 ac[0].init(); 119 for(i=0; i<n; ++i){ 120 scanf("%s", s); 121 Insert(s); 122 } 123 scanf("%s",s); 124 BuildAC(); 125 printf("Case %d: %d\n", ++t, Solve(s)); 126 } 127 }
有兴趣的话可以参考:
http://blog.sina.com.cn/s/blog_6635898a0102e1ig.html
以上是关于poj 3769DNArepair的主要内容,如果未能解决你的问题,请参考以下文章