题目链接

Problem Description
Dr. X is a biologist, who likes rabbits very much and can do everything for them. 2012 is coming, and Dr. X wants to take some rabbits to Noah's Ark, or there are no rabbits any more.

A rabbit's genes can be expressed as a string whose length is l (1 ≤ l ≤ 100) containing only 'A', 'G', 'T', 'C'. There is no doubt that Dr. X had a in-depth research on the rabbits' genes. He found that if a rabbit gene contained a particular gene segment, we could consider it as a good rabbit, or sometimes a bad rabbit. And we use a value W to measure this index.

We can make a example, if a rabbit has gene segment "ATG", its W would plus 4; and if has gene segment "TGC", its W plus -3. So if a rabbit's gene string is "ATGC", its W is 1 due to ATGC contains both "ATG"(+4) and "TGC"(-3). And if another rabbit's gene string is "ATGATG", its W is 4 due to one gene segment can be calculate only once.

Because there are enough rabbits on Earth before 2012, so we can assume we can get any genes with different structure. Now Dr. X want to find a rabbit whose gene has highest W value. There are so many different genes with length l, and Dr. X is not good at programming, can you help him to figure out the W value of the best rabbit.

 
Input
There are multiple test cases. For each case the first line is two integers n (1 ≤ n ≤ 10),l (1 ≤ l ≤ 100), indicating the number of the particular gene segment and the length of rabbits' genes.

The next n lines each line contains a string DNAi and an integer wi (|wi| ≤ 100), indicating this gene segment and the value it can contribute to a rabbit's W.

 
Output
For each test case, output an integer indicating the W value of the best rabbit. If we found this value is negative, you should output "No Rabbit after 2012!".
 
Sample Input
2 4
ATG 4
TGC -3
1 6
TGC 4
4 1
A -1
T -2
G -3
C -4
 
Sample Output
4
4
No Rabbit after 2012!

 
Hint

case 1:we can find a rabbit whose gene string is ATGG(4), or ATGA(4) etc.

case 2:we can find a rabbit whose gene string is TGCTGC(4), or TGCCCC(4) etc.
case 3:any gene string whose length is 1 has a negative W.
 
题意:现在有n个基因片段(用包含A、G、T、C的字符串表示),每个基因片段有一个权值,现在求长为L的基因的最大权值(每个基因片段重复出现算一次,不用计算多次)?
 
思路:AC自动机+状态压缩DP,dp[i][j][s]表示长为 i 的基因且在AC自动机 tire树上匹配到节点 j 时包含基因片段集合为 s 时合法(即dp[i][j][s]=1,如果等于0 则表示不存在这样的基因),那么由长为 i 的字符串可以递推到长为 i+1 的字符串基因, x=node[j].son[k]->id 和  f=node[j].son[k]->flag => dp[i+1][x][s|f]=1  (0<=k<=3), 最后计算长为L的基因最大权值和,根据dp[L][j][s] 遍历所有节点的所有状态,计算每个状态下的权值和,得到最大权值和。
 
注意:dp每次根据前一长度下的状态 推 下一长度下的状态,那么可以使用滚动数组减小存储空间。
 
代码如下:
  1. #include <iostream>
  2. #include <algorithm>
  3. #include <cstdio>
  4. #include <cstring>
  5. #include <queue>
  6. #include <string>
  7. using namespace std;
  8. const int N=;
  9. int a[],tot;
  10. struct Node
  11. {
  12. Node *fail;
  13. Node *son[];
  14. int flag;
  15. int id;
  16. }node[N],*root;
  17. queue<Node*>Q;
  18. bool dp[][N][];
  19.  
  20. int f(char c)
  21. {
  22. if(c=='A') return ;
  23. if(c=='G') return ;
  24. if(c=='T') return ;
  25. if(c=='C') return ;
  26. }
  27. void insert(string s,int id)
  28. {
  29. Node *now=root;
  30. for(int i=;i<s.length();i++)
  31. {
  32. int x=f(s[i]);
  33. if(now->son[x]==NULL) now->son[x]=&node[tot++];
  34. now=now->son[x];
  35. }
  36. now->flag|=(<<(id-));
  37. }
  38. void build()
  39. {
  40. Q.push(root);
  41. while(!Q.empty())
  42. {
  43. Node *now=Q.front(); Q.pop();
  44. for(int i=;i<;i++)
  45. {
  46. if(now->son[i])
  47. {
  48. Node *p=now->fail;
  49. while(p&&(!(p->son[i]))) p=p->fail;
  50. now->son[i]->fail=(p)?(p->son[i]):root;
  51. now->son[i]->flag|=now->son[i]->fail->flag;
  52. Q.push(now->son[i]);
  53. }
  54. else now->son[i]=(now!=root)?now->fail->son[i]:root;
  55. }
  56. }
  57. }
  58. void init()
  59. {
  60. tot=;
  61. root=&node[];
  62. memset(dp,,sizeof(dp));
  63. while(!Q.empty()) Q.pop();
  64. for(int i=;i<N;i++)
  65. {
  66. node[i].fail=NULL;
  67. node[i].flag=;
  68. node[i].id=i;
  69. for(int j=;j<;j++) node[i].son[j]=NULL;
  70. }
  71. }
  72. int main()
  73. {
  74. int n,l;
  75. while(scanf("%d%d",&n,&l)!=EOF)
  76. {
  77. init();
  78. for(int i=;i<=n;i++)
  79. {
  80. string s; cin>>s;
  81. insert(s,i);
  82. scanf("%d",&a[i]);
  83. }
  84. build();
  85. dp[][][]=;
  86. int cn=;
  87. for(int i=;i<l;i++)
  88. {
  89. cn^=;
  90. memset(dp[cn],,sizeof(dp[cn]));
  91. for(int j=;j<tot;j++)
  92. {
  93. for(int s=;s<(<<n);s++)
  94. {
  95. if(!dp[cn^][j][s]) continue;
  96. for(int k=;k<;k++)
  97. {
  98. int x=node[j].son[k]->id;
  99. int f=node[j].son[k]->flag;
  100. dp[cn][x][s|f]=;
  101. }
  102. }
  103. }
  104. }
  105. int ans=-;
  106. for(int i=;i<tot;i++)
  107. {
  108. for(int s=;s<(<<n);s++)
  109. {
  110. if(!dp[cn][i][s]) continue;
  111. int tmp=;
  112. int x=s;
  113. for(int k=;k<=n;k++)
  114. {
  115. if(x&) tmp+=a[k];
  116. x>>=;
  117. }
  118. ans=max(ans,tmp);
  119. }
  120. }
  121. if(ans<) puts("No Rabbit after 2012!");
  122. else printf("%d\n",ans);
  123. }
  124. return ;
  125. }

hdu 4057--Rescue the Rabbit(AC自动机+状压DP)的更多相关文章

  1. HDU 4057 Rescue the Rabbit ( AC自动机 + 状态压缩DP )

    模板来自notonlysuccess. 模式串只有10个,并且重复出现的分值不累加,因此很容易想到状态压缩. 将模式串加入AC自动机,最多有10*100个状态. dp[i][j][k]:串长为i,在T ...

  2. zoj3545Rescue the Rabbit (AC自动机+状压dp+滚动数组)

    Time Limit: 10 Seconds      Memory Limit: 65536 KB Dr. X is a biologist, who likes rabbits very much ...

  3. HDU 3247 Resource Archiver(AC自动机 + 状压DP + bfs预处理)题解

    题意:目标串n( <= 10)个,病毒串m( < 1000)个,问包含所有目标串无病毒串的最小长度 思路:貌似是个简单的状压DP + AC自动机,但是发现dp[1 << n][ ...

  4. hdu 6086 -- Rikka with String(AC自动机 + 状压DP)

    题目链接 Problem Description As we know, Rikka is poor at math. Yuta is worrying about this situation, s ...

  5. HDU 2825 Wireless Password(AC自动机 + 状压DP)题解

    题意:m个密码串,问你长度为n的至少含有k个不同密码串的密码有几个 思路:状压一下,在build的时候处理fail的时候要用 | 把所有的后缀都加上. 代码: #include<cmath> ...

  6. HDU 4057 Rescue the Rabbit(AC自动机+DP)

    题目链接 一个数组开小了一点点,一直提示wa,郁闷,这题比上个题简单一点. #include <iostream> #include <cstring> #include &l ...

  7. HDU - 2825 Wireless Password (AC自动机+状压DP)

    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=2825 题意:给一些字符串,构造出长度为n的字符串,它至少包含k个所给字符串,求能构造出的个数. 题解: ...

  8. hdu 2825 aC自动机+状压dp

    Wireless Password Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others ...

  9. BZOJ1559 [JSOI2009]密码 【AC自动机 + 状压dp】

    题目链接 BZOJ1559 题解 考虑到这是一个包含子串的问题,而且子串非常少,我们考虑\(AC\)自动机上的状压\(dp\) 设\(f[i][j][s]\)表示长度为\(i\)的串,匹配到了\(AC ...

随机推荐

  1. 团队作业8----第二次项目冲刺(beta阶段)5.25

    Day7-05.25 1.每日会议 会议内容: 1.今日对整个项目进行了一个总结. 2.讨论了这次项目中的不足和每个人的贡献. 讨论照片:拍摄者 周迪 2.任务分配情况: 每个人的工作分配表: 队员 ...

  2. 201521123109《java程序设计》第八周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结集合与泛型相关内容. 1.2 选做:收集你认为有用的代码片段 2. 书面作业 本次作业题集集合 List中指定元素的删除(题目4-1 ...

  3. 201521123008《Java程序设计》第七周实验总结

    1.本周学习总结 以你喜欢的方式(思维导图或其他)归纳总结集合相关内容. 2. 书面作业 1.ArrayList代码分析 1.1 解释ArrayList的contains源代码 public bool ...

  4. 201521123101 《Java程序设计》第2周学习总结

    1. 本周学习总结 使用码云保存管理自己的代码: 学习String和Array: 继续对JAVA的探索,希望以后能在编程上更顺畅一些 2. 书面作业 1.使用Eclipse关联jdk源代码(截图),并 ...

  5. 201521123052《Java程序设计》第2周学习总结

    1. 本周学习总结 String类一些用法 学习Array类 使用枚举 使用eclipse关联JDK源代码 使用码云管理云代码 2.书面作业 1.使用Eclipse关联jdk源代码,并查看String ...

  6. 201521123030《Java程序设计》第1周学习总结

    #1. 本章学习总结 你对于本章知识的学习总结 了解了java的发展简介 认识了jvm/jre/jdk的联系,学习安装jdk java好麻烦的说... 1.为什么java程序可以跨平台运行?执行jav ...

  7. 201521123017 《Java程序设计》第14周学习总结

    1. 本周学习总结 2. 书面作业 Q1.MySQL数据库基本操作 建立数据库,将自己的姓名.学号作为一条记录插入.(截图,需出现自己的学号.姓名) 在自己建立的数据库上执行常见SQL语句(截图) - ...

  8. 201521123122 《java程序设计》第十一周学习总结

    ## 201521123122 <java程序设计>第十一周实验总结 ## 1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多线程相关内容. 其实这周也没讲多少内容,所 ...

  9. latch session allocation

    应用反馈上午10点左右出现大量应用连接数据库报错 采集9点-10点和10点-11点的AWR报告进行分析 DB时间明显差异,再继续分析等待事件 可以看出有session相关的Latch等待事件,查看相关 ...

  10. 内置open()函数对外部文件的操作

    >>> file=open('c://333.csv','r') 一些基本打开关闭操作 >>> s=file.read() >>> print s ...