题目大意:

改动文本串的上的字符,使之不出现上面出现的串。问最少改动多少个。

思路分析:

dp[i][j]表示如今 i 个字符改变成了字典树上的 j 节点。

然后顺着自己主动机一直转移方程。

注意合法与不合法。

  1. #include <cstdio>
  2. #include <iostream>
  3. #include <cstring>
  4. #include <algorithm>
  5. #define inf 0x3f3f3f3f
  6. using namespace std;
  7.  
  8. const char tab = 0;
  9. const int max_next = 4;
  10. int idx;
  11. struct trie
  12. {
  13. struct trie *fail;
  14. struct trie *next[max_next];
  15. int isword;
  16. int index;
  17. trie()
  18. {
  19. isword=0;
  20. memset(next,NULL,sizeof next);
  21. fail=NULL;
  22. }
  23. };
  24. int rev[256];
  25. trie *que[100005],ac[100005];
  26. int head,tail;
  27.  
  28. trie *New()
  29. {
  30. trie *temp=&ac[idx];
  31. for(int i=0;i<4;i++)temp->next[i]=NULL;
  32. temp->fail=NULL;
  33. temp->isword=0;
  34. temp->index=idx++;
  35. return temp;
  36. }
  37. void Insert(trie *root,char *word,int len){
  38. trie *t=root;
  39. for(int i=0;i<len;i++){
  40. if(t->next[rev[word[i]]]==NULL)
  41. t->next[rev[word[i]]]=New();
  42. t=t->next[rev[word[i]]];
  43. }
  44. t->isword++;
  45. }
  46.  
  47. void acbuild(trie *root){
  48. int head=0,tail=0;
  49. que[tail++]=root;
  50. root->fail=NULL;
  51. while(head<tail){
  52. trie *temp=que[head++],*p;
  53. for(int i=0;i<max_next;i++){
  54. if(temp->next[i]){
  55. if(temp==root)temp->next[i]->fail=root;
  56. else {
  57. p=temp->fail;
  58. while(p!=NULL){
  59. if(p->next[i]){
  60. temp->next[i]->fail=p->next[i];
  61. break;
  62. }
  63. p=p->fail;
  64. }
  65. if(p==NULL)temp->next[i]->fail=root;
  66. }
  67. if(temp->next[i]->fail->isword)temp->next[i]->isword++;
  68. que[tail++]=temp->next[i];
  69. }
  70. else if(temp==root)temp->next[i]=root;
  71. else temp->next[i]=temp->fail->next[i];
  72. }
  73. }
  74. }
  75.  
  76. void del(trie *root)
  77. {
  78. for(int i=0;i<max_next;i++)
  79. if(root->next[i])del(root->next[i]);
  80. free(root);
  81. }
  82.  
  83. int dp[2005][2005];
  84. int solve(char *word,int len)
  85. {
  86. memset(dp,0x3f,sizeof dp);
  87. dp[0][0]=0;
  88. for(int i=1;i<=len;i++)
  89. {
  90. for(int j=0;j<idx;j++)
  91. {
  92. if(ac[j].isword)continue;
  93. if(dp[i-1][j]==inf)continue;
  94. for(int k=0;k<4;k++)
  95. {
  96. int p=ac[j].next[k]->index;
  97. if(ac[p].isword)continue;
  98. dp[i][p]=min(dp[i][p],dp[i-1][j]+(k!=rev[word[i-1]]));
  99. }
  100. }
  101. }
  102. int ans=inf;
  103. for(int i=0;i<idx;i++)
  104. ans=min(ans,dp[len][i]);
  105. return ans==inf?
  106.  
  107. -1:ans;
  108. }
  109. char word[10005];
  110. int main()
  111. {
  112. rev['A']=0;
  113. rev['G']=1;
  114. rev['C']=2;
  115. rev['T']=3;
  116.  
  117. int n,cas=1;
  118. while(scanf("%d",&n)!=EOF && n)
  119. {
  120. idx=0;
  121. trie *root=New();
  122. for(int i=1;i<=n;i++)
  123. {
  124. scanf("%s",word);
  125. Insert(root,word,strlen(word));
  126. }
  127. acbuild(root);
  128. scanf("%s",word);
  129. printf("Case %d: %d\n",cas++,solve(word,strlen(word)));
  130. }
  131. return 0;
  132. }

Hdu 2457 DNA repair (ac自己主动机+dp)的更多相关文章

  1. 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: ...

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

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

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

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

  4. HDU 2457 DNA repair (AC自动机+DP)

    题意:给N个串,一个大串,要求在最小的改变代价下,得到一个不含上述n个串的大串. 思路:dp,f[i][j]代表大串中第i位,AC自动机上第j位的最小代价. #include<algorithm ...

  5. HDU 2457 DNA repair(AC自动机+DP)题解

    题意:给你几个模式串,问你主串最少改几个字符能够使主串不包含模式串 思路:从昨天中午开始研究,研究到现在终于看懂了.既然是多模匹配,我们是要用到AC自动机的.我们把主串放到AC自动机上跑,并保证不出现 ...

  6. poj 3691 DNA repair(AC自己主动机+dp)

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

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

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

  8. HDU 2825 Wireless Password (AC自己主动机,DP)

    pid=2825">http://acm.hdu.edu.cn/showproblem.php? pid=2825 Wireless Password Time Limit: 2000 ...

  9. HDU 2896 病毒侵袭 (AC自己主动机)

    pid=2896">http://acm.hdu.edu.cn/showproblem.php?pid=2896 病毒侵袭 Time Limit: 2000/1000 MS (Java ...

随机推荐

  1. PHP——面向对象

    <body> <?php //类调用用:: //对象调用用-> class Dog1//定义类 { //成员属性(变量) var $name; var $age; var $p ...

  2. Android基础总结(九)多媒体

    多媒体概念(了解) 文字.图片.音频.视频 计算机图片大小的计算(掌握) 图片大小 = 图片的总像素 * 每个像素占用的大小 单色图:每个像素占用1/8个字节 16色图:每个像素占用1/2个字节 25 ...

  3. js 调试问题

    ***********06.  $(this).index() 失效****************************** 使用的库函数jquery 版本过低,1.4以上即可 ********* ...

  4. 测试网站访问速度的方法(GTmetrix)

     全方位的免费网站速度测试工具 — GTmetrix 它结合了Google Page Speed和Yahoo! YSlow的网页速度测试功能,并且提供可行的建议帮你改善网站速度.会根据网站的具体情况, ...

  5. when case group by 的用法集合

    1.用那个以前大家都熟悉的例子,要求是依旧下面的表格求每个大洲的人口总和 国家(countrcoungry) 人口(population) 中国 600 美国 100 加拿大 100 英国 200 法 ...

  6. hdu 2857:Mirror and Light(计算几何,点关于直线的对称点,求两线段交点坐标)

    Mirror and Light Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  7. 如何用ChemDraw选择结构

    在使用ChemDraw软件过程中,我们往往会需要对结构进行翻滚.连结.旋转.分解.组合等操作.但是对于新手用户来说不是每种操作大家都会使用的. 针对这种情况我们会有一系列的教程来为大家讲解.下面我们就 ...

  8. BEGIN_MESSAGE_MAP(Caccess_test_1Dlg, CDialogEx)

    BEGIN_MESSAGE_MAP(...消息映射宏的一部分.ON_WM_CREATE()产生一个消息处理函数映射项目,把WM_CREATE和OnCreate函数联系起来. 参数的个数和类型是系统已经 ...

  9. ionic跳转(二)

    1)网上说要想在js里跳转用,$state.go()方法,但找了大半天都没找到在ionic使用$state的方法 2)要想用js跳转,直接用原生js跳转也是可以的 location.href='#ho ...

  10. Android无线测试之—UiAutomator UiScrollable API介绍四

    获取与设置最大滚动次数常量值 一.获取与设置最大滚动次数常量值相关API 返回值 API 描述 int getMaxSearchSwipes() 获取执行搜索滑动过程中的最大滑动次数,默认最大滚动次数 ...