链接

当时是因为没有做出来这道题才开了自动机的专题,现在看看还是比较简单的。

因为每个病毒串只算一次,只有10个病毒串,可以状压一下哪些状态是可以达到的,最后取一个最大值。

  1. #include <iostream>
  2. #include<cstdio>
  3. #include<cstring>
  4. #include<algorithm>
  5. #include<stdlib.h>
  6. #include<vector>
  7. #include<cmath>
  8. #include<queue>
  9. #include<set>
  10. #include<string>
  11. using namespace std;
  12. #define N 1005
  13. #define LL long long
  14. #define INF 0xfffffff
  15. const double eps = 1e-;
  16. const double pi = acos(-1.0);
  17. const double inf = ~0u>>;
  18. const int child_num = ;
  19. char vir[];
  20. int v[];
  21. class AC
  22. {
  23. private:
  24. int ch[N][child_num];
  25. int fail[N];
  26. int Q[N];
  27. int val[N];
  28. int sz;
  29. int id[];
  30. int dp[][N][<<];
  31. char s[N];
  32. public:
  33. void init()
  34. {
  35. fail[] = ;
  36. id['A'] = ,id['G'] = ,id['T'] = ,id['C'] = ;
  37. }
  38. void reset()
  39. {
  40. memset(ch[],,sizeof(ch[]));
  41. memset(val,,sizeof(val));
  42. sz = ;
  43. }
  44. void insert(char *a,int key)
  45. {
  46. int p = ;
  47. for(; *a ; a++)
  48. {
  49. int d= id[*a];
  50. if(ch[p][d]==)
  51. {
  52. memset(ch[sz],,sizeof(ch[sz]));
  53. s[sz] = *a;
  54. ch[p][d] = sz++;
  55. }
  56. p = ch[p][d];
  57. }
  58. val[p] = (<<key);
  59. }
  60. void construct()
  61. {
  62. int i,head=,tail = ;
  63. for(i = ; i < child_num ;i++)
  64. {
  65. if(ch[][i])
  66. {
  67. fail[ch[][i]] = ;
  68. Q[tail++] = ch[][i];
  69. }
  70. }
  71. while(head!=tail)
  72. {
  73. int u = Q[head++];
  74. val[u]|=val[fail[u]];
  75. for(i = ; i < child_num ; i++)
  76. {
  77. if(ch[u][i])
  78. {
  79. fail[ch[u][i]] = ch[fail[u]][i];
  80. Q[tail++] = ch[u][i];
  81. }
  82. else ch[u][i] = ch[fail[u]][i];
  83. }
  84. }
  85. }
  86. void work(int n,int m)
  87. {
  88. int i,j,g;
  89. memset(dp,,sizeof(dp));
  90. dp[][][] = ;
  91. for(i = ;i < n ;i++)
  92. {
  93. memset(dp[(i+)%],,sizeof(dp[(i+)%]));
  94. for(j = ;j < sz ; j++)
  95. {
  96. for(int e = ; e < (<<m) ; e++)
  97. {
  98. if(!dp[i%][j][e]) continue;
  99. for(g = ; g < child_num ; g++)
  100. {
  101. int o = val[ch[j][g]];
  102. dp[(i+)%][ch[j][g]][e|o] = dp[i%][j][e];
  103. }
  104. }
  105. }
  106. }
  107. int cnt = -INF;
  108. for(i = ;i < sz ; i++)
  109. {
  110. for(j = ;j < (<<m) ; j++)
  111. {
  112. int ans = ;
  113. if(!dp[n%][i][j]) continue;
  114. for(g = ; g < m ;g++)
  115. {
  116. if(j&(<<g))
  117. ans+=v[g];
  118. }
  119. cnt = max(ans,cnt);
  120. }
  121. }
  122. if(cnt<)
  123. puts("No Rabbit after 2012!");
  124. else
  125. printf("%d\n",cnt);
  126. }
  127. }ac;
  128. int main()
  129. {
  130. int n,i,m;
  131. ac.init();
  132. while(scanf("%d%d",&m,&n)!=EOF)
  133. {
  134. ac.reset();
  135. for(i = ;i <= m ;i++)
  136. {
  137. scanf("%s%d",vir,&v[i-]);
  138. ac.insert(vir,i-);
  139. }
  140. ac.construct();
  141. ac.work(n,m);
  142. }
  143. return ;
  144. }

hdu4057Rescue the Rabbit(ac自动机+dp)的更多相关文章

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

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

  2. POJ1625 Censored!(AC自动机+DP)

    题目问长度m不包含一些不文明单词的字符串有多少个. 依然是水水的AC自动机+DP..做完后发现居然和POJ2778是一道题,回过头来看都水水的... dp[i][j]表示长度i(在自动机转移i步)且后 ...

  3. HDU2296 Ring(AC自动机+DP)

    题目是给几个带有价值的单词.而一个字符串的价值是 各单词在它里面出现次数*单词价值 的和,问长度不超过n的最大价值的字符串是什么? 依然是入门的AC自动机+DP题..不一样的是这题要输出具体方案,加个 ...

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

    题目一串DNA最少需要修改几个基因使其不包含一些致病DNA片段. 这道题应该是AC自动机+DP的入门题了,有POJ2778基础不难写出来. dp[i][j]表示原DNA前i位(在AC自动机上转移i步) ...

  5. hdu 4117 GRE Words AC自动机DP

    题目:给出n个串,问最多能够选出多少个串,使得前面串是后面串的子串(按照输入顺序) 分析: 其实这题是这题SPOJ 7758. Growing Strings AC自动机DP的进阶版本,主题思想差不多 ...

  6. hdu 2457(ac自动机+dp)

    题意:容易理解... 分析:这是一道比较简单的ac自动机+dp的题了,直接上代码. 代码实现: #include<stdio.h> #include<string.h> #in ...

  7. HDU 2425 DNA repair (AC自动机+DP)

    DNA repair Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  8. HDU2296——Ring(AC自动机+DP)

    题意:输入N代表字符串长度,输入M代表喜欢的词语的个数,接下来是M个词语,然后是M个词语每个的价值.求字符串的最大价值.每个单词的价值就是单价*出现次数.单词可以重叠.如果不止一个答案,选择字典序最小 ...

  9. tyvj P1519 博彩游戏(AC自动机+DP滚动数组)

    P1519 博彩游戏 背景 Bob最近迷上了一个博彩游戏…… 描述 这个游戏的规则是这样的:每花一块钱可以得到一个随机数R,花上N块钱就可以得到一个随机序列:有M个序列,如果某个序列是产生的随机序列的 ...

随机推荐

  1. gets(),fgets()的作用机制探究

    gets(),fgets() scanf("%d",&a)若接受形如 2 这样的输入后,缓冲区内会留一个\n,此后若调用gets等函数时会读出这个换行出现错误,需注意 fg ...

  2. 8 ways rich people view the world differently than the average person

    Self-made millionaire Steve Siebold spent 26 years interviewing some of the wealthiest people in the ...

  3. Microsoft ACE OLEDB 12.0概念及用法

    首先需要清楚几个概念: Database engine(数据引擎):一些预先存储于数据库中的组件: Microsoft JET (Joint Engine Technology):Microsoft ...

  4. Pycharm 2016 2 激活

    选其中一款,一个不行换另一个 1. 选License server激活,输入:http://114.215.133.70:41017/ 2. 43B4A73YYJ-eyJsaWNlbnNlSWQiOi ...

  5. C++函数模板template

    一.  问题: 强类型语言要求我们为所有希望比较的类型都实现一个实例 int min(int a, int b) { return a < b ? a : b; } double min(dou ...

  6. 史上最易懂的Android jni开发资料--NDK环境搭建

    谷歌改良了ndk的开发流程,对于Windows环境下NDK的开发,如果使用的NDK是r7之前的版本,必须要安装Cygwin才能使用NDK.而在NDKr7开始,Google的Windows版的NDK提供 ...

  7. js setInterval

    var monitorInterval = null;    //检索cs 是否处理完成 开始: monitorInterval = setInterval(function () { CheckCS ...

  8. Windows Azure Mangement API 之 更方便的使用Mangement API

    许多.Net 程序员在使用Azure Management API的时候都选择参考微软官方示例,通过创建HttpWebRequest来创建. 或者自己创建类库来封装这些API,使之调用起来更加方便. ...

  9. IE8 下 select option 内容过长 , 展开时信息显示不全解决办法

    IE8 下 select option 内容过长 , 展开时信息显示不全 , 简单折衷的方式就是给 option 加上 title 属性 , 但是又不想一个个的修改,怎么办呢,代码如下 : //sel ...

  10. 使用 Centos 7 的 systemctl 管理服务

    CentOS 7的服务systemctl脚本存放在:/usr/lib/systemd/,有系统(system)和用户(user)之分,像需要开机不登陆就能运行的程序,存系统服务里即:/usr/lib/ ...