Time Limit: 10 Seconds      Memory Limit: 65536 KB


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 highestW 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

  1. 2 4
  2. ATG 4
  3. TGC -3
  4.  
  5. 1 6
  6. TGC 4
  7.  
  8. 4 1
  9. A -1
  10. T -2
  11. G -3
  12. C -4

Sample Output

  1. 4
  2. 4
  3. 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个模板串,每一个模板串对应一个数值,有正也有负,然你构造一个长度为m的模板串,使得模板串的价值最大,且一种模板串如果重复出现只统计一次。

思路:考虑到n<=10,所以用状压dp的思想,设状态为dp[i][j][state]表示走了i步,当前节点为j,含有的单词状态为state的最大值。但是这个状态消耗的内存太大,有100*1000*1024,所以用滚动数组(这点是看了别人的题解才发现的,果然意识不够啊..= .=),然后构造trie图,dp就行了。

  1. #include<iostream>
  2. #include<stdio.h>
  3. #include<stdlib.h>
  4. #include<string.h>
  5. #include<math.h>
  6. #include<vector>
  7. #include<map>
  8. #include<set>
  9. #include<queue>
  10. #include<stack>
  11. #include<string>
  12. #include<algorithm>
  13. using namespace std;
  14. typedef long long ll;
  15. #define inf 99999999
  16. #define pi acos(-1.0)
  17. #define maxnode 1100
  18. int t0,t1,t2,t3;
  19. char s[14],str[50];
  20. int cas=0;
  21. int dp[2][1005][1030],w[1030];
  22. int n,m;
  23. struct trie{
  24. int sz,root,val[maxnode],next[maxnode][4],fail[maxnode];
  25. int q[1111111];
  26. void init(){
  27. int i;
  28. sz=root=0;
  29. val[0]=0;
  30. for(i=0;i<4;i++){
  31. next[root][i]=-1;
  32. }
  33. }
  34. int idx(char c){
  35. if(c=='A')return 0;
  36. if(c=='C')return 1;
  37. if(c=='T')return 2;
  38. if(c=='G')return 3;
  39. }
  40. void charu(char *s,int index){
  41. int i,j,u=0;
  42. int len=strlen(s);
  43. for(i=0;i<len;i++){
  44. int c=idx(s[i]);
  45. if(next[u][c]==-1){
  46. sz++;
  47. val[sz]=0;
  48. next[u][c]=sz;
  49. u=next[u][c];
  50. for(j=0;j<4;j++){
  51. next[u][j]=-1;
  52. }
  53. }
  54. else{
  55. u=next[u][c];
  56. }
  57. }
  58. val[u]|=(1<<index-1);
  59. }
  60. void build(){
  61. int i,j;
  62. int front,rear;
  63. front=1;rear=0;
  64. for(i=0;i<4;i++){
  65. if(next[root][i]==-1 ){
  66. next[root][i]=root;
  67. }
  68. else{
  69. fail[next[root][i] ]=root;
  70. rear++;
  71. q[rear]=next[root][i];
  72. }
  73. }
  74. while(front<=rear){
  75. int x=q[front];
  76. val[x]|=val[fail[x] ];
  77. front++;
  78. for(i=0;i<4;i++){
  79. if(next[x][i]==-1){
  80. next[x][i]=next[fail[x] ][i];
  81. }
  82. else{
  83. fail[next[x][i] ]=next[fail[x] ][i];
  84. rear++;
  85. q[rear]=next[x][i];
  86. }
  87. }
  88. }
  89. }
  90. void solve(){
  91. int i,j,state,t,state1;
  92. for(j=0;j<=sz;j++){
  93. for(state=0;state<(1<<n);state++){
  94. dp[0][j][state]=dp[1][j][state]=-inf;
  95. }
  96. }
  97. int tot=0;
  98. dp[tot][0][0]=0;
  99. for(i=0;i<m;i++){
  100. for(j=0;j<=sz;j++){
  101. for(state=0;state<(1<<n);state++){
  102. if(dp[tot][j][state]==-inf)continue;
  103. for(t=0;t<4;t++){
  104. state1=(state|val[next[j][t] ]);
  105. dp[1^tot ][next[j][t] ][state1]=max(dp[1^tot ][next[j][t] ][state1],w[state1] );
  106. }
  107. }
  108. }
  109. tot=1^tot;
  110. for(j=0;j<=sz;j++){
  111. for(state=0;state<(1<<n);state++){
  112. dp[1^tot][j][state]=-inf;
  113. }
  114. }
  115. }
  116. int maxx=-inf;
  117. for(j=0;j<=sz;j++){
  118. for(state=0;state<(1<<n);state++){
  119. maxx=max(maxx,dp[tot][j][state]);
  120. }
  121. }
  122. if(maxx<0){
  123. printf("No Rabbit after 2012!\n");
  124. }
  125. else printf("%d\n",maxx);
  126. }
  127. }ac;
  128. int main()
  129. {
  130. int i,j;
  131. int value[20],len,state;
  132. while(scanf("%d%d",&n,&m)!=EOF)
  133. {
  134. ac.init();
  135. for(i=1;i<=n;i++){
  136. scanf("%s%d",&s,&value[i]);
  137. len=strlen(s);
  138. if(len>m)continue;
  139. ac.charu(s,i);
  140. }
  141. for(state=0;state<(1<<n);state++){
  142. w[state]=0;
  143. for(i=1;i<=n;i++){
  144. if(state&(1<<(i-1) )){
  145. w[state]+=value[i];
  146. }
  147. }
  148. }
  149. ac.build();
  150. ac.solve();
  151. }
  152. return 0;
  153. }

zoj3545Rescue the Rabbit (AC自动机+状压dp+滚动数组)的更多相关文章

  1. hdu 4057--Rescue the Rabbit(AC自动机+状压DP)

    题目链接 Problem Description Dr. X is a biologist, who likes rabbits very much and can do everything for ...

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

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

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

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

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

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

  5. hdu2825 Wireless Password(AC自动机+状压dp)

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission ...

  6. HDU 4057:Rescue the Rabbit(AC自动机+状压DP)***

    http://acm.hdu.edu.cn/showproblem.php?pid=4057 题意:给出n个子串,串只包含‘A’,'C','G','T'四种字符,你现在需要构造出一个长度为l的串,如果 ...

  7. HDU4057 Rescue the Rabbit(AC自动机+状压DP)

    题目大概是给几个DNA片段以及它们各自的权值,如果一个DNA包含某个片段那么它的价值就加上这个片段的权值,同时包含多个相同DNA片段也只加一次,问长度l的DNA可能的最大价值. 与HDU2825大同小 ...

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

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

  9. UVALive - 4126 Password Suspects (AC自动机+状压dp)

    给你m个字符串,让你构造一个字符串,包含所有的m个子串,问有多少种构造方法.如果答案不超过42,则按字典序输出所有可行解. 由于m很小,所以可以考虑状压. 首先对全部m个子串构造出AC自动机,每个节点 ...

随机推荐

  1. 【Java基础】多线程

    多线程 基本概念 程序(program)是为完成特定任务.用某种语言编写的一组指令的集合.即指一段静态的代码,静态对象. 进程(process)是程序的一次执行过程,或是正在运行的一个程序.是一个动态 ...

  2. LeetCode 371两数之和

    题目描述: 不使用运算符 + 和 - ​​​​​​​,计算两整数 ​​​​​​​a .b ​​​​​​​之和. 思路: 既然不能使用运算符操作就要考虑到,位运算的加法. 加法有进位的时候和不进位的时候 ...

  3. Lnux:实验 Linux C 编程

    实验题目: 实验 3 Linux C 编程 实验目的和要求:   熟悉 Linux 操作系统环境 在 Linux 下编写.执行简单的 C 程序 用 C 语言写自己的 Linux 命令 实验过程: 认真 ...

  4. [从源码学设计]蚂蚁金服SOFARegistry之配置信息

    [从源码学设计]蚂蚁金服SOFARegistry之配置信息 目录 [从源码学设计]蚂蚁金服SOFARegistry之配置信息 0x00 摘要 0x01 业务范畴 1.1 配置作用 1.2 学习方向 0 ...

  5. ALV中的分隔条(SPLITTER_CONTROL)

    如上图,可以做成左右的分割,当然也可以做成上下的分割效果,在每个分割的容器内,显示各自的内容. 需要使用的class: cl_gui_splitter_container, cl_gui_custom ...

  6. vue2.0、vue3.0不同之处

    一.响应式赋值操作不同 Vue2.0 1.通过data返回对象做相应: 2.对复杂的对象或数组下的属性等深层次的改变需要通过$set的方式. Vue3.0 1.ref实现简单的实现响应,通过value ...

  7. Bitter.Core系列十一:Bitter ORM NETCORE ORM 全网最粗暴简单易用高性能的 NETCore 之 字段变更收集器

    有时候我们业务层需要记录 数据库表更改之前的值和更改之后的值的记录集合--此过程在 Bitter.Core 中有强有力的支持.Bitter.Core 字段收集器提供了方便简单易用的 收集对象在修改之前 ...

  8. 树莓派zero 使用usb串口连接

    使用minicom连接bash$ lsusbBus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hubBus 001 Device 0 ...

  9. Slack 的想法很好啊,很有创新,牛。

    [原]https://www.leiphone.com/news/201411/aXHUpe4ZFI2sSwpb.html 由于以往一些用于办公的应用反响平平,因此对迅速崛起的办公交流应用Slack, ...

  10. 逻辑bug 测试用例

    1. 179. 最大数 - 力扣(LeetCode) https://leetcode-cn.com/problems/largest-number/ 给定一组非负整数 nums,重新排列它们每个数字 ...