题目大意:

要求构造一个串,使得这个串是由所给的串相连接构成,连接能够有重叠的部分。

思路分析:

首先用所给的串建立自己主动机,每一个单词节点记录当前节点可以达到的最长后缀。

開始的时候想的是dp[i][j]表示长度为i,走到自己主动机的j节点的答案。

可是显然既然是能够反复覆盖的,那么每个节点的dp值都并非最优的。由于能够从一个地方截断去连接另外一个串。

所以正确姿势就是dp [i] [j] [k] 表示构造到了长度为 i 的串, 如今这个串后面有k 个字符是没有找到有效的节点的,然后在自己主动机上走到了j。

那么转移的时候,就有两种情况。

isword >= k+1。

。。

为什么是k+1 由于我们如今是去找的儿子节点,已经加1了。这种话就是这个节点能够全然覆盖没有匹配到的k个。换句话说就是让后面的k个字符找到了合法节点去匹配。那么就转移到dp [i+1] [j->next] [0]...

否则,假设k+1<=10 那么就让后面这个继续失配,那么久直接转移到 dp [i+1][j->next][k+1]...

最后累加答案。

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

Codeforces 86C Genetic engineering (AC自己主动机+dp)的更多相关文章

  1. hdu4758 Walk Through Squares (AC自己主动机+DP)

    Walk Through Squares Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others ...

  2. HDU - 4758 Walk Through Squares (AC自己主动机+DP)

    Description   On the beaming day of 60th anniversary of NJUST, as a military college which was Secon ...

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

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

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

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

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

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

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

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

  7. hdu4057 Rescue the Rabbit(AC自己主动机+DP)

    Rescue the Rabbit Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...

  8. Zoj 3535 Gao the String II (AC自己主动机+dp)

    题目大意: 用集合A中的串构造出一个串,使之让很多其它的setB中的串成为他的子串. 思路分析: 和 Codeforces 86C 几乎相同. 只是这里是要用A中的构造. 先用A 和 B的串构造一个自 ...

  9. HDU - 4511 小明系列故事――女友的考验(AC自己主动机+DP)

    Description 最终放寒假了,小明要和女朋友一起去看电影.这天,女朋友想给小明一个考验,在小明正准备出发的时候.女朋友告诉他.她在电影院等他,小明过来的路线必须满足给定的规则:  1.如果小明 ...

随机推荐

  1. ArcGIS Pro体验04——菜单栏

    对菜单栏进行熟悉一下: 1.地图菜单 剪切板(Clipboard):剪切(Cut).复制(Copy).粘贴(Paste),这些不用说了,在ArcMap中是放在"编辑"菜单下面的.当 ...

  2. 开源 免费 java CMS - FreeCMS1.5-数据对象-job

    下载地址:http://code.google.com/p/freecms/ job 从FreeCMS 1.5 开始支持 在使用职位相关标签时,标签会封装job供页面调用. 属性 说明 id id s ...

  3. Struts2(五)Action二配置

    一.method参数 action package com.pb.web.action; public class HourseAction { public String add(){ System ...

  4. Java从零开始学六(运算符)

    运算符 一.赋值运算符号 No. 赋值运算符号 描述 1 = 赋值 int num=22; System.out.println("num= "+num); num=num-3; ...

  5. OA项目实战学习(7)——初始化数据&amp;权限配置显示

    详细有哪些功能: 初始化数据 权限数据. 超级管理员. Installer.java package cn.xbmu.oa.install; import javax.annotation.Resou ...

  6. Oracle 12c CDB PDB

    先说基本用法: 先按11G之前进行 conn / as sysdba; create user test identifed by test; ORA-65096: 公用用户名或角色名无效. 查官方文 ...

  7. [Unity-1] Unity简单介绍

    Unity是一套包含图形.声音.物理等功能的游戏引擎,提供了一个强大的关卡编辑器.支持大部分主流3D软件格式,使用C#或者JavaScript等高级语言实现脚本功能.使开发人员无需了解底层复杂技术,高 ...

  8. 基于LumiSoft.Net.dll发、收、删邮件

    发邮件: using LumiSoft.Net.SMTP.Client; Mime m = new Mime(); MimeEntity mainEntity = m.MainEntity; // F ...

  9. lambda 2

    # -*- coding: utf-8 -*- #python 27 #xiaodeng def action(x): return (lambda y:x+y) act=action(99) pri ...

  10. 在阿里云上进行Docker集群的自动弹性伸缩

    摘要: 在刚刚结束的云栖大会上,阿里云容器服务演示了容器的自动弹性伸缩,能够从容应对互联网应用的峰值流量.阿里云容器服务不仅支持容器级别的自动弹性伸缩,也支持集群节点级别的自动弹性伸缩.从而真正做到从 ...