这题目是去年大连regional的题目,当时比赛的时候已经看出是道自动机+dp的题目了,但是无奈当时自己的自动机基础太弱了,被虐了一顿。今天再来做这道题目,感觉还好,思路还是蛮清晰的,但是却看出了长时间写代码少代码能力的不足。。。一个<=写成了<然后昨天WA了一晚上。。。

这题和传统的自动机+dp差不多,主要区别在于每个带权基因串只计算一次,需要用状态压缩(字符串个数最大只有10个)。dp[l][n][state]表示长度为l的字符串,后缀为自动机中第n类状态(自动机中每个节点代表一类状态),是否可取道带权基因串组合状态为state的情况;如果可以dp[l][n][state]为true,否则为false。计算的时候和大部分自动机dp一样,暴力递推求解就可以了。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <map>
#include <string>
#include <utility>
#include <algorithm>
using namespace std;const int N = 10;struct node {int num, index;node *pre, *next[4];void init() {num = index = 0;pre = 0;memset(next, 0, sizeof(next));}
};int n, l, cnt, val[10], sval[1<<N];
bool dp[2][N*150][1<<N];
char str[150];map <char, int> h;
node trie[N*150];
node *root, *queue[N*150];void insertStr(node *root, char *str, int pos) {int lab, len = strlen(str);for(int i = 0; i < len; i++) {lab = h[str[i]];if(root->next[lab] == NULL) {root->next[lab] = &trie[++cnt];root->next[lab]->init();root->next[lab]->index = cnt;}root = root->next[lab];}root->num |= (1<<pos);
}void buildAC() {int head, tail;node *u;root->pre = root;head = tail = 0;queue[0] = root;while(head <= tail) {u = queue[head++];u->num |= u->pre->num;for(int i = 0; i < 4; i++) {if(u->next[i] == 0) {if(u == root)  u->next[i] = root;else  u->next[i] = u->pre->next[i];}else {if(u == root)  u->next[i]->pre = root;else  u->next[i]->pre = u->pre->next[i];queue[++tail] = u->next[i];}}}
}int main() {//freopen("data.in", "r", stdin);h['A'] = 0; h['G'] = 1; h['T'] = 2; h['C'] = 3;while(scanf("%d%d", &n, &l) != EOF) {memset(trie, 0, sizeof(trie));root = &trie[0];root->init();cnt = 0;for(int i = 0; i < n; i++) {scanf(" %s%d", str, &val[i]);insertStr(root, str, i);}memset(sval, 0, sizeof(sval));for(int state = 0; state < (1<<n); state++) {for(int j = 0; j < n; j++)if(state&(1<<j))sval[state] += val[j];}buildAC();memset(dp, false, sizeof(dp));int u, v;u = 0;dp[u][0][0] = true;for(int i = 0; i < l; i++) {v = u^1;memset(dp[v], false, sizeof(dp[v]));for(int j = 0; j <= cnt; j++)for(int k = 0; k < (1<<n); k++) {if(!dp[u][j][k])  continue;else {for(int p = 0; p < 4; p++) {int dindex = trie[j].next[p]->index;dp[v][dindex][k|trie[dindex].num] = true;}}}u = v;}int ans = -1;for(int i = 0; i <= cnt; i++)for(int j = 0; j < (1<<n); j++) {if(dp[u][i][j] == false)  continue;ans = max(ans, sval[j]);}if(ans != -1)  printf("%d\n", ans);else  printf("No Rabbit after 2012!\n");}return  0;
}

转载于:https://www.cnblogs.com/fCarver7/archive/2012/09/20/2696036.html

ZOJ3545——AC自动机+状态dp相关推荐

  1. hdu 2825 Wireless Password AC自动机+状态DP

    时间卡得紧,写成递推可以做一些优化 //#pragma comment(linker, "/STACK:1024000000,1024000000") #include<cs ...

  2. 【HDU3530】 [Sdoi2014]数数 (AC自动机+数位DP)

    3530: [Sdoi2014]数数 Time Limit: 10 Sec  Memory Limit: 512 MB Submit: 682  Solved: 364 Description 我们称 ...

  3. 【bzoj3530】[Sdoi2014]数数 AC自动机+数位dp

    题目描述 我们称一个正整数N是幸运数,当且仅当它的十进制表示中不包含数字串集合S中任意一个元素作为其子串.例如当S=(22,333,0233)时,233是幸运数,2333.20233.3223不是幸运 ...

  4. 【BZOJ3530】数数(SDOI2014)-AC自动机+数位DP

    测试地址:数数 做法:本题需要用到AC自动机+数位DP. 首先看到多模式串匹配,自然想到用AC自动机来做.用AC自动机构造出状态转移图后,令f(i,j,k)f(i,j,k)f(i,j,k)为匹配了最高 ...

  5. 洛谷 P-4045 密码(AC自动机+状态压缩+数位DP+乱搞)

    洛谷 P-4045 密码 记AC的第一道黑题! 题意:已知一段密码包含了一些字符串,然后求满足条件的密码有多少个,数量小于42时还得全部输出 思路: 一开始WA了两个点,不知道WA的什么,索性把读入的 ...

  6. HDU 3341 Lost's revenge(AC自动机+状态压缩DP)

    Description 给出N个优良的基因段,每段长度小于等于10,只含有AGCT四种碱基. 现给一段基因片段S,|S|<=40.对其重排列后,最多能含有多少个优良基因,基因段可以有公共部分 I ...

  7. AC自动机 + 概率dp + 高斯消元 --- HDU 5955 or 2016年沈阳icpc H [AC自动机 + 概率dp + 高斯消元]详解

    题目链接 题目大意: 就是有NNN个人,每个人都会猜一个长度为LLL的只包含{1,2,3,4,5,6}\{1,2,3,4,5,6\}{1,2,3,4,5,6}的序列,现在裁判开始投掷骰子,并且把每次的 ...

  8. HDU3247 Resource Archiver(AC自动机+BFS+DP)

    题目,求最短的包含所有n个DNA片段且不包含任何一个病毒片段的序列. 容易用所有DNA片段和病毒片段建一个AC自动机,构造fail时处理一下各个结点后缀是DNA或者病毒的情况,然后dp[S][u]表示 ...

  9. 【BZOJ2553】禁忌,AC自动机+期望DP+矩乘

    传送门 先考虑选最多禁忌串的问题 感受一下,如果禁忌串之间没有包含关系,一定是可以从前往后贪心搞的,直接建AC自动机跑匹配,找到一个禁忌串的末尾就回到根上,并把禁忌串数量+1 (所以起初我想的是把包含 ...

最新文章

  1. 新兴机器学习算法:迁移学习
  2. Destroy it!
  3. Android 4.4.2 动态添加JNI库方法记录 (二 app应用层)
  4. mysql check table_修复MySQL的MyISAM表命令check table用法
  5. [css] scroll-snap-align属性的应用场景是什么?
  6. 之前接触过的测试的相关工具
  7. visio图标_弱电间机柜原型图整理,可编辑!(Excel,visio,CAD)
  8. Linux工作笔记030---Centos7.3启动tomcat 输入startup.sh后提示command not found
  9. 进程queue和线程queue
  10. silverlight 学习笔记 (八):Prism中MEF的初步认识
  11. javascript中对象的深度克隆
  12. 计算机思维和数学的那些事
  13. 小白能读懂的 《手把手教你学DSP(TMS320X281X)》第六章 使用c语言操作dsp寄存器(以SCI为例进行说明))
  14. 京东的焦虑:强制996,高管离职,奶茶风波...
  15. java vo层_java的几种对象(PO,VO,DAO,BO,POJO)解释
  16. asp.net 使用UrlRewritingNet.UrlRewriter组件URL重写,伪静态详解
  17. C语言——整数直角三角形
  18. 2411681-87-1,Thalidomide-O-PEG4-t-butyl ester化学式:C28H38N2O11
  19. ZLib的数据压缩和解压缩
  20. ipc原理linux,Docker 的底层原理,了解它只需要 5分钟!

热门文章

  1. adb 查看屏幕大小_蚂蚁森林自动收取能量、偷取能量、浇水(使用adb、python)...
  2. 怎样手动给无线网设置一个DNS服务器地址,无线网的dns怎样设置.docx
  3. java mvc上传文件进度_java相关:springMVC+ajax实现文件上传且带进度条实例
  4. c# 数组中的空值_C# 数据操作系列 - 1. SQL基础操作
  5. 通过官方查看springCloud,springBoot版本对应关系
  6. oracle恢复drop建的表首次,Oracle中Drop,Delete,Truancate表恢复
  7. c语言switch结构计算利润,求助。。关于用switch编写简易计算器
  8. linux dd 硬盘 脚本,如何使用dd命令测试Linux磁盘的读写速度
  9. java使用btree_java数据结构之二叉树遍历的非递归实现
  10. java坦克大战总体功能设计_java课程设计——坦克大战