DNA repair
Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 5877   Accepted: 2760

Description

Biologists finally invent techniques of repairing DNA that contains segments causing kinds of inherited diseases. For the sake of simplicity, a DNA is represented as a string containing characters 'A', 'G' , 'C' and 'T'. The repairing techniques are simply
to change some characters to eliminate all segments causing diseases. For example, we can repair a DNA "AAGCAG" to "AGGCAC" to eliminate the initial causing disease segments "AAG", "AGC" and "CAG" by changing two characters. Note that the repaired DNA can
still contain only characters 'A', 'G', 'C' and 'T'.

You are to help the biologists to repair a DNA by changing least number of characters.

Input

The input consists of multiple test cases. Each test case starts with a line containing one integers N (1 ≤ N ≤ 50), which is the number of DNA segments causing inherited diseases.

The following N lines gives N non-empty strings of length not greater than 20 containing only characters in "AGCT", which are the DNA segments causing inherited disease.

The last line of the test case is a non-empty string of length not greater than 1000 containing only characters in "AGCT", which is the DNA to be repaired.

The last test case is followed by a line containing one zeros.

Output

For each test case, print a line containing the test case number( beginning with 1) followed by the

number of characters which need to be changed. If it's impossible to repair the given DNA, print -1.

Sample Input

  1. 2
  2. AAA
  3. AAG
  4. AAAG
  5. 2
  6. A
  7. TG
  8. TGAATG
  9. 4
  10. A
  11. G
  12. C
  13. T
  14. AGT
  15. 0

Sample Output

  1. Case 1: 1
  2. Case 2: 4
  3. Case 3: -1

Source

题意:

给定N个模式串(1 ≤ N ≤ 50) 最大长度为20,一个主串(长最大为1000),同意涉及的字符为4个 {'A','T','G','C'},求最少改动几个字符 使主串不包括全部模式串。

思路:

对模式串建立AC自己主动机。依据AC自己主动机来dp。

dp[i][j]表示到主串第i个字符时到达自己主动机上第j个节点时改动最少字符数。

枚举下一个字符为AGCT中的一个来转移,注意转移的时候不能包括模式串中的节点,于是要用一个数组来记录该节点结尾时是否包括了单词。

代码:

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <cstring>
  4. #include <algorithm>
  5. #include <queue>
  6. using namespace std;
  7.  
  8. const int INF=0x3f3f3f3f;
  9. const int maxn=10010;
  10. const int bsz=26;
  11. typedef long long ll;
  12. char txt[maxn],cc[]="AGCT";
  13. bool vis[maxn];
  14. int ans;
  15.  
  16. struct Trie
  17. {
  18. bool have[maxn]; // 该节点结尾是否包括单词
  19. int ch[maxn][bsz],val[maxn],sz,cnt[maxn]; // ch存Trie val-节点相应的单词 cnt-节点结尾单词个数
  20. int f[maxn],last[maxn];//f-失配指针 last-后缀链接
  21. int newnode()
  22. {
  23. val[sz]=0; cnt[sz]=0; have[sz]=0;
  24. memset(ch[sz],-1,sizeof ch[sz]);
  25. return sz++;
  26. }
  27. void init()
  28. {
  29. sz=0;
  30. newnode();
  31. }
  32. int idx(char c) // 取c的标号 详细看字符为什么
  33. {
  34. return c-'A';
  35. }
  36. void Insert(char *st,int id)
  37. {
  38. int u=0,n=strlen(st),c,i;
  39. for(i=0;i<n;i++)
  40. {
  41. c=idx(st[i]);
  42. if(ch[u][c]==-1)
  43. ch[u][c]=newnode();
  44. u=ch[u][c];
  45. }
  46. val[u]=id;
  47. cnt[u]++;
  48. have[u]=1;
  49. }
  50. void build()
  51. {
  52. int u=0,v,i;
  53. queue<int> q;
  54. f[0]=0;
  55. for(i=0;i<bsz;i++)
  56. {
  57. v=ch[u][i];
  58. if(v==-1) ch[u][i]=0;
  59. else
  60. {
  61. f[v]=0;
  62. q.push(v);
  63. }
  64. }
  65. while(!q.empty())
  66. {
  67. u=q.front();
  68. q.pop();
  69. last[u]=val[f[u]]?
  70.  
  71. f[u]:last[f[u]];
  72. for(i=0;i<bsz;i++)
  73. {
  74. v=ch[u][i];
  75. if(v==-1) ch[u][i]=ch[f[u]][i]; // 将NULL变为有意义 沿着父亲失配指针走第一个有意义的节点
  76. else
  77. {
  78. f[v]=ch[f[u]][i];
  79. have[v]|=have[f[v]];
  80. q.push(v);
  81. }
  82. }
  83. }
  84. }
  85. bool Find(char *st,int m,int id)
  86. {
  87. int n=strlen(st),i,u=0,c,p,flag=0;
  88. // vis-可标记哪些单词出现过 相同的单词仅仅标记一个
  89. for(i=0;i<n;i++)
  90. {
  91. c=idx(st[i]);
  92. u=ch[u][c];
  93. p=val[u]?
  94.  
  95. u:last[u];
  96. while(p)
  97. {
  98. vis[val[p]]=true;
  99. //if(val[p]){ ans+=cnt[p]; cnt[p]=0; }
  100. flag=1;
  101. p=last[p];
  102. }
  103. }
  104. if(!flag) return false;
  105. //能够将出现的单词标号输出
  106. // for(i=1;i<=m;i++)
  107. // if(vis[i])
  108. // {
  109. // vis[i]=0;
  110. // printf(" %d",i);
  111. // }
  112. // puts("");
  113. return true;
  114. }
  115. } ac;
  116. int dp[1005][1005];
  117.  
  118. void solve()
  119. {
  120. int i,j,k,len=strlen(txt+1);
  121. int id,next;
  122. memset(dp,0x3f,sizeof(dp));
  123. dp[0][0]=0;
  124. for(i=0;i<len;i++)
  125. {
  126. for(j=0;j<ac.sz;j++)
  127. {
  128. if(dp[i][j]>=INF) continue ;
  129. for(k=0;k<4;k++)
  130. {
  131. id=ac.idx(cc[k]);
  132. next=ac.ch[j][id];
  133. if(ac.have[next]) continue ;
  134. if(cc[k]==txt[i+1])
  135. {
  136. dp[i+1][next]=min(dp[i+1][next],dp[i][j]);
  137. }
  138. else
  139. {
  140. dp[i+1][next]=min(dp[i+1][next],dp[i][j]+1);
  141. }
  142. }
  143. }
  144. }
  145. ans=INF;
  146. for(j=0;j<ac.sz;j++) ans=min(ans,dp[len][j]);
  147. if(ans>=INF) ans=-1;
  148. }
  149. int main()
  150. {
  151. int i,j,n,ca=0;
  152. while(~scanf("%d",&n))
  153. {
  154. if(n==0) break ;
  155. ac.init();
  156. for(i=1;i<=n;i++)
  157. {
  158. scanf("%s",txt);
  159. ac.Insert(txt,i);
  160. }
  161. ac.build();
  162. scanf("%s",txt+1);
  163. solve();
  164. printf("Case %d: %d\n",++ca,ans);
  165. }
  166. return 0;
  167. }

poj 3691 DNA repair(AC自己主动机+dp)的更多相关文章

  1. POJ 2778 DNA Sequence (AC自己主动机 + dp)

    DNA Sequence 题意:DNA的序列由ACTG四个字母组成,如今给定m个不可行的序列.问随机构成的长度为n的序列中.有多少种序列是可行的(仅仅要包括一个不可行序列便不可行).个数非常大.对10 ...

  2. Hdu 2457 DNA repair (ac自己主动机+dp)

    题目大意: 改动文本串的上的字符,使之不出现上面出现的串.问最少改动多少个. 思路分析: dp[i][j]表示如今 i 个字符改变成了字典树上的 j 节点. 然后顺着自己主动机一直转移方程. 注意合法 ...

  3. POJ 3691 &amp; HDU 2457 DNA repair (AC自己主动机,DP)

    http://poj.org/problem?id=3691 http://acm.hdu.edu.cn/showproblem.php?pid=2457 DNA repair Time Limit: ...

  4. HDU 2457/POJ 3691 DNA repair AC自动机+DP

    DNA repair Problem Description   Biologists finally invent techniques of repairing DNA that contains ...

  5. POJ 3691 DNA repair(AC自动机+DP)

    题目链接 能AC还是很开心的...此题没有POJ2778那么难,那个题还需要矩阵乘法,两个题有点相似的. 做题之前,把2778代码重新看了一下,回忆一下当时做题的思路,回忆AC自动机是干嘛的... 状 ...

  6. poj 1699 Best Sequence(AC自己主动机+如压力DP)

    id=1699" target="_blank" style="">题目链接:poj 1699 Best Sequence 题目大意:给定N个D ...

  7. POJ 1625 Censored! (AC自己主动机 + 高精度 + DP)

    题目链接:Censored! 解析:AC自己主动机 + 高精度 + 简单DP. 字符有可能会超过128.用map映射一下就可以. 中间的数太大.得上高精度. 用矩阵高速幂会超时,简单的DP就能解决时间 ...

  8. Hdu 3341 Lost&#39;s revenge (ac+自己主动机dp+hash)

    标题效果: 举个很多种DNA弦,每个字符串值值至1.最后,一个长字符串.要安排你最后一次另一个字符串,使其没事子值和最大. IDEAS: 首先easy我们的想法是想搜索的!管她3721..直接一个字符 ...

  9. HDU - 2825 Wireless Password(AC自己主动机+DP)

    Description Liyuan lives in a old apartment. One day, he suddenly found that there was a wireless ne ...

随机推荐

  1. Codeforces Round #247 (Div. 2) ABC

    Codeforces Round #247 (Div. 2) http://codeforces.com/contest/431  代码均已投放:https://github.com/illuz/Wa ...

  2. How to make a combo box with fulltext search autocomplete support?

    I would like a user to be able to type in the second or third word from a TComboBoxitem and for that ...

  3. Spring MVC概述

    Spring MVC框架是一个开源的Java平台,为开发强大的基于Java的Web应用程序提供全面的基础架构支持非常容易和非常快速. Spring框架最初由Rod Johnson撰写,并于2003年6 ...

  4. appium+python自动化58-xpath定位

    基本属性定位 以淘宝app为例,定位左上角扫一扫按钮 1.可以通过text文本定位到 //*[@text='text文本属性'] # 定位text driver.find_element_by_xpa ...

  5. python接口自动化9-https请求(SSL)

    前言 本来最新的requests库V2.13.0是支持https请求的,但是一般写脚本时候,我们会用抓包工具fiddler,这时候会报:requests.exceptions.SSLError: [S ...

  6. 一次delete速度异常慢的处理过程

    InnoDB delete from xxx速度暴慢原因 博客分类: database MySQLPythonMobile多线程SQL  step1,一个简单的联系人表 CREATE TABLE `c ...

  7. Hive QL——深入浅出学Hive

    第一部分:DDL DDL •建表 •删除表 •修改表结构 •创建/删除视图 •创建数据库 •显示命令 建表 CREATE [EXTERNAL] TABLE [IF NOT EXISTS] table_ ...

  8. iOS开源项目:FlatUIKit

    FlatUIKit是iOS中具有扁平化风格的UI(Flat UI)组件.FlatUIKit的设计灵感来源于Flat UI和Kyle Miller.FlatUIKit中的组件是通过扩展(category ...

  9. 【Hibernate步步为营】--hql查询小介

    HQL 是指Hibernate Query Language,它是Hibernate的查询语言,拥有一套自己的查询机制,它的查询语句和SQL非常类似.在使用的时候可以非常快上手.HQL提供了基本上SQ ...

  10. Reverse Integer--整数的反转

    原题: Reverse digits of an integer. =>反转一个整数的数字.例子如下: Example1: x = 123, return 321 Example2: x = - ...