poj 3691
来源:互联网 发布:淘宝订单信息编辑 编辑:程序博客网 时间:2024/06/06 09:37
AC自动机的失配函数的利用和DP,Trie图中的每个节点代表一种状态,即一个字符串的后缀为从根节点到本节点的字符串。就是说把字符串根据他的后缀分为不同的类别,AC自动机上的每一个节点代表一个类别。在一个字符串的后面再加一个字符,此字符串就会从Tire图中的一个节点转移到另一个节点,这个过程可通过失配函数的求解过程中求出。其中有的节点所代表的类是不合法的,要记录下来。然后就是dp,ans[i][j]表示母串的i长度的串要变成状态为j的串所需最小修改次数。初始化为无穷大,如果j不合法不求,并且j的下一个转移得到的节点也不从j转移得到,最后比较每个节点的ans[len][j],得到最小值。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <queue> 5 using namespace std; 6 const int maxn=50+10; 7 const int inf=0x3f3f3f3f; 8 int n; 9 int ch[maxn*20][4]; 10 int val[maxn*20],tot,f[maxn*20]; 11 int ans[1000+10][maxn*20]; 12 int getV(char c) 13 { 14 switch(c) 15 { 16 case 'A':return 0; 17 case 'G':return 1; 18 case 'C':return 2; 19 case 'T':return 3; 20 } 21 } 22 void Insert(char *s) 23 { 24 int u=0,len=strlen(s),i,tv; 25 for(i=0;i<len;i++) 26 { 27 tv=getV(s[i]); 28 if(!ch[u][tv]) ch[u][tv]=tot++; 29 u=ch[u][tv]; 30 } 31 val[u]=1; 32 } 33 void getFail() 34 { 35 queue<int> q; 36 f[0]=0; 37 int i,u; 38 for(i=0;i<4;i++) 39 { 40 u=ch[0][i]; 41 if(u) 42 { 43 f[u]=0; 44 q.push(u); 45 //printf("%d %d\n",u,val[u]); 46 } 47 } 48 int v,r; 49 while(!q.empty()) 50 { 51 r=q.front();q.pop(); 52 for(i=0;i<4;i++) 53 { 54 u=ch[r][i]; 55 if(!u) { ch[r][i]=ch[f[r]][i]; } 56 else 57 { 58 if(val[r]) val[u]=1;//这部很关键 59 q.push(u); 60 v=f[r]; 61 while(v&&!ch[v][i]) v=f[v]; 62 f[u]=ch[v][i]; 63 if(val[f[u]]) val[u]=1;//这步很关键 64 } 65 // printf("%d %d\n",u,val[u]); 66 } 67 } 68 } 69 int main() 70 { 71 int cas=0; 72 while(scanf("%d",&n)&&n) 73 { 74 int i,j; 75 char s[1000+10]; 76 tot=1; 77 memset(ch,0,sizeof(ch)); 78 memset(val,0,sizeof(val)); 79 for(i=0;i<n;i++) 80 { 81 scanf("%s",s); 82 Insert(s); 83 } 84 scanf("%s",s); 85 getFail(); 86 int len=strlen(s); 87 for(i=0;i<=len;i++) 88 { 89 for(j=0;j<tot;j++) 90 ans[i][j]=inf; 91 } 92 ans[0][0]=0; 93 int k,v; 94 for(i=0;i<len;i++) 95 { 96 for(j=0;j<tot;j++) 97 { 98 if(ans[i][j]<inf) 99 {100 for(k=0;k<4;k++)101 {102 if(!val[ch[j][k]])103 {104 v=ch[j][k];105 ans[i+1][v]=min(ans[i+1][v],ans[i][j]+(getV(s[i])==k?0:1));106 }107 }108 }109 }110 }111 int re=inf;112 for(i=0;i<tot;i++) re=min(re,ans[len][i]);113 printf("Case %d: %d\n",++cas,re<inf?re:-1);114 }115 return 0;116 }
- poj 3691
- poj 3691
- poj 3691
- poj 3691
- poj 3691 DNA repair
- POJ 3691 DNA repair
- POJ 3691 DNA repair
- POJ - 3691 DNA repair
- poj 3691 DAN repair
- POJ
- poj
- POJ
- POJ
- poj
- poj
- POJ
- POJ
- poj
- poj 1815
- poj 3928
- poj 2287
- Jenkins+Maven+SVN搭建自动部署,自动测试环境
- hdu 3714
- poj 3691
- POJ-2739-Sum of Consecutive Prime Numbers
- hdu 2825
- hdu 4547
- poj 2778
- poj 1743
- poj 3261
- 仿百度文库、豆丁在线阅读
- poj 1947