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!".

题目大意:给n个串,每个串有一个权值,若一个串包含这些串,就把权值累加起来。问一个长度为L的串权值最多为多少。

思路:http://blog.sina.com.cn/s/blog_7da04dd30100xnux.html

代码(460MS):

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <algorithm>
  4. #include <cstring>
  5. #include <queue>
  6. using namespace std;
  7. typedef long long LL;
  8.  
  9. const int MAXN = ;
  10. const int MAXL = ;
  11. const int size = ;
  12.  
  13. char str[] = "ATCG";
  14.  
  15. struct Node {
  16. int val;
  17. Node *go[size], *fail;
  18. } StatePool[MAXN];
  19. int ncnt;
  20.  
  21. void init() {
  22. memset(StatePool, , ncnt * sizeof(Node));
  23. ncnt = ;
  24. }
  25.  
  26. Node* new_node() {
  27. return &StatePool[ncnt++];
  28. }
  29.  
  30. void insert(Node* root, char s[], int id) {
  31. Node *p = root;
  32. for(int i = ; s[i]; ++i) {
  33. int idx = strchr(str, s[i]) - str;
  34. if(!p->go[idx]) p->go[idx] = new_node();
  35. p = p->go[idx];
  36. }
  37. p->val |= ( << id);
  38. }
  39.  
  40. queue<Node*> que;
  41. void makeFail(Node* root) {
  42. root->fail = root;
  43. que.push(root);
  44. while(!que.empty()) {
  45. Node *tmp = que.front(); que.pop();
  46. for(int i = ; i < size; ++i) {
  47. if(!tmp->go[i]) {
  48. tmp->go[i] = tmp == root ? root : tmp->fail->go[i];
  49. //if(tmp->go[i] == NULL) puts("error");
  50. } else {
  51. Node *q = tmp->go[i];
  52. q->fail = tmp == root ? root : tmp->fail->go[i];
  53. q->val |= q->fail->val;
  54. que.push(tmp->go[i]);
  55. }
  56. }
  57. }
  58. }
  59.  
  60. bool dp[][MAXN][MAXN], (*pre)[MAXN], (*now)[MAXN];
  61. char s[MAXN];
  62. int weight[MAXN];
  63. int n, L;
  64.  
  65. inline int encode(Node *p) {
  66. return p - StatePool;
  67. }
  68.  
  69. inline Node* decode(int idx) {
  70. return &StatePool[idx];
  71. }
  72.  
  73. int solve(Node *root) {
  74. pre = dp[], now = dp[];
  75. memset(now, , sizeof(dp[]));
  76. now[encode(root)][] = true;
  77. for(int _ = ; _ < L; ++_) {
  78. swap(pre, now);
  79. memset(now, , sizeof(dp[]));
  80. for(int i = ; i < ncnt; ++i) {
  81. Node *p = decode(i);
  82. for(int st = ; st < ( << n); ++st) if(pre[i][st]) {
  83. for(int k = ; k < size; ++k)
  84. now[encode(p->go[k])][st | p->go[k]->val] = true;
  85. }
  86. }
  87. }
  88. int res = -;
  89. for(int i = ; i < ncnt; ++i) {
  90. for(int st = ; st < ( << n); ++st) if(now[i][st]) {
  91. int t = ;
  92. for(int j = ; j < n; ++j)
  93. if((st >> j) & ) t += weight[j];
  94. res = max(res, t);
  95. }
  96. }
  97. return res;
  98. }
  99.  
  100. int main() {
  101. while(scanf("%d%d", &n, &L) != EOF) {
  102. init();
  103. Node *root = new_node();
  104. for(int i = ; i < n; ++i) {
  105. scanf("%s%d", s, &weight[i]);
  106. insert(root, s, i);
  107. }
  108. makeFail(root);
  109. int res = solve(root);
  110. if(res >= ) printf("%d\n", res);
  111. else puts("No Rabbit after 2012!");
  112. }
  113. }

ZOJ 3545 Rescue the Rabbit(AC自动机+状压DP)(The 2011 ACM-ICPC Asia Dalian Regional Contest)的更多相关文章

  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. zoj3545Rescue the Rabbit (AC自动机+状压dp+滚动数组)

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

  3. Zoj 3545 Rescue the Rabbit(ac自己主动机+dp)

    标题效果: 鉴于DNA有一个正确的顺序值.请构造一个长度I的DNA在这个序列使DNA正确的顺序值极大.它被认为是负的输出噼啪. .. IDEAS: 施工顺序是,ac己主动机上走,求最大要用到dp dp ...

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

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

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

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

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. MYSQL启动报1067错误,系统日志中是“服务 mysql 意外停止” Mysql日志中则是:“Plugin \'FEDERATED\' is disabled”

    MYSQL启动报1067错误,系统日志中是"服务 mysql 意外停止" Mysql日志中则是:"Plugin \'FEDERATED\' is disabled&quo ...

  2. GATT 服务器与客户端角色

    两个设备应用数据的通信是通过协议栈的GATT层实现的.从GATT角度来看,当两个设备建立连接后,他们处于以下两种角色之一: GATT服务器: 它是为GATT客户端提供数据服务的设备 GATT客户端:  ...

  3. centos的vi常用用法

    centos的vi常用用法 vi编辑器是所有Unix及Linux系统下标准的编辑器,它的强大不逊色于任何最新的文本编辑器,这里只是简单地介绍一下它的用法和一小部分指令.由于对Unix及Linux系统的 ...

  4. 【Java 基础篇】【第一课】HelloWorld

    有点C++基础,现在需要快速的学会java,掌握java,所以就这样了,写点博客,以后看起来也好回顾. 1.第一步 javaSDK和Eclipse下载就不说了,搞定了这两样之后: 2.打开Eclips ...

  5. php--group by

    1. GROUP BY 是分组查询, 一般 GROUP BY 是和聚合函数配合使用 group by 有一个原则,就是 select 后面的所有列中,没有使用聚合函数的列,必须出现在 group by ...

  6. Selenium2学习-033-WebUI自动化实战实例-031-页面快照截图应用之二 -- 区域截图

    我在之前的文章中曾给出浏览器显示区域截图的方法,具体请参阅 .或许,有些小主已经想到了,每次都获取整个显示区域的截图存储,那么经过一段时间后,所使用的图片服务器的容量将会受到极大的挑战,尤其是在产品需 ...

  7. Sql server与Excel的数据互通导入导出

    现在,我先从Sql server数据表导出到Excel中,再从Excel数据表导出到Sql server中: 一.Sql server数据表导出到Excel中: 1.新建一个Excel,选择“数据”菜 ...

  8. C# 常用日期函数

    我想知道取的时期是几月.几日,然后做一些统计,上网找了一些方法. --DateTime 数字型 System.DateTime currentTime=new System.DateTime(); 1 ...

  9. 异步刷新tableView

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ [self.tableView rel ...

  10. table tricks