对AC自动机+DP题的一些汇总与一丝总结 (1)
(1)题意 : 输入n、m、k意思就是给你 m 个模式串,问你构建长度为 n 至少包含 k 个模式串的方案有多少种
分析:(HDU2825)
DP[i][j][k] 表示 DP[第几步][哪个节点结尾][当前选了哪些单词] = 方案数
for(int i=; i<=n; i++)
for(int j=; j<ac.Size; j++)
for(int l=; l<(<<m); l++)
dp[i][j][l] = ;
dp[][][] = ;
for(int i=; i<n; i++){
for(int j=; j<ac.Size; j++){
for(int l=; l<(<<m); l++){
if(dp[i][j][l] > ){
for(int x=; x<Letter; x++){
int newi = i+;
int newj = ac.Node[j].Next[x];
int newl = (ac.Node[ newj ].id) | l;
dp[newi][newj][newl] += dp[i][j][l];
dp[newi][newj][newl] %= MOD;
}
}
}
}
}
(2)题意 : 给出 n 个模式串,最后给出一个主串,问你主串打乱重组的情况下,最多能够包含多少个模式串。(只有ATGC四总字符)(HDU3341)
(也就是说,给定了字母数量的限制去构造)
DP[A][T][G][C][Node]前四维表示ATGC数量,最后一维表示当前状态停留在节点 Node
即利用一个四维数组 Hash[11][11][11][11] ( 每一个字母最多就是 10 个,所以这样开数组 ) ,然后只需要统计主串各个种类字符的数量,
for(int j=; j<=ac.Size; j++)
for(int i=; i<=HashCnt; i++)
dp[i][j] = -; dp[][] = ; for(int A=; A<=num[]; A++){
for(int T=; T<=num[]; T++){
for(int G=; G<=num[]; G++){
for(int C=; C<=num[]; C++){
for(int i=; i<ac.Size; i++){
int j = Hash[A][T][G][C];
if(dp[j][i] >= ){
for(int k=; k<; k++){
if(k== && A == num[]) continue;
if(k== && T == num[]) continue;
if(k== && G == num[]) continue;
if(k== && C == num[]) continue;
int a, t, g, c;
a = (k==), t = (k==);
g = (k==), c = (k==);
dp[Hash[A+a][T+t][G+g][C+c]][ac.Node[i].Next[k]]
= max(dp[Hash[A+a][T+t][G+g][C+c]][ac.Node[i].Next[k]],
dp[j][i] + ac.Node[ac.Node[i].Next[k]].cnt);
}
}
}
}
}
}
}
(3)题意 : 给出一个 n 行、m 列的方格图,现从图左上角(0, 0) 到右下角的 (n, m)走出一个字符串(规定只能往下或者往右走),向右走代表' R ' 向下走则是代表 ' D ' 最后从左上角到右下角,不同的路线会走出不同的字符串,问你这些不同的字符串有多少个是包含了接下来给定的两个子串。(HDU 4758)
(用 (n+1) 个 ' D ' 和 (m+1)个 ' R ' 构造出长度为 (n+m+2) 的字符串,且包含给定的两个子串的方案数有多少个)
DP[i][j][k][l]代表在有 i 个 ' D '(即向下走了 i 步)、j 个 ' R '(向右走 j 步)、停留在 k 这个节点、包含子串情况 l 时的最大方案.
for(int i=; i<=n; i++)
for(int j=; j<=m; j++)
for(int k=; k<ac.Size; k++)
for(int l=; l<; l++)
dp[i][j][k][l] = ; dp[][][][] = ; for(int i=; i<=n; i++){
for(int j=; j<=m; j++){
for(int k=; k<ac.Size; k++){
for(int l=; l<; l++){
if(dp[i][j][k][l] > ){
int Node1 = ac.Node[k].Next[];
int Node2 = ac.Node[k].Next[];
dp[i][j+][Node1][l | ac.Node[Node1].id] += dp[i][j][k][l];
dp[i+][j][Node2][l | ac.Node[Node2].id] += dp[i][j][k][l];
dp[i][j+][Node1][l | ac.Node[Node1].id] %= MOD;
dp[i+][j][Node2][l | ac.Node[Node2].id] %= MOD;
}
}
}
}
}
我们可以发现:题目3其实就是题目2和题目1的结合
1.对于是给出字符数量限制的,我们一般在DP的时候加维度表示字符数量的情况:比如dp[A][T][G][C][] 前四维表示ATGC数量
2.对于是包含模式串的限制,我们一般在DP的时候加维度(二进制)表示选了哪些串m,切AC自动机的节点需要保留选串的情况
(Node[now].id |= (1<<id);)
3.我们在一些题目中还发现了,AC自动机节点是求一个(Node[now].cnt++;) 这是一般问包含多少个模式窜
Node[now].falt =1; 这是标记哪些是给出的模式串 这些保留的变量是看情况而定
对AC自动机+DP题的一些汇总与一丝总结 (1)的更多相关文章
- 对AC自动机+DP题的一些汇总与一丝总结 (2)
POJ 2778 DNA Sequence (1)题意 : 给出m个病毒串,问你由ATGC构成的长度为 n 且不包含这些病毒串的个数有多少个 关键字眼:不包含,个数,长度 DP[i][j] : 表示长 ...
- HDU2296 Ring(AC自动机+DP)
题目是给几个带有价值的单词.而一个字符串的价值是 各单词在它里面出现次数*单词价值 的和,问长度不超过n的最大价值的字符串是什么? 依然是入门的AC自动机+DP题..不一样的是这题要输出具体方案,加个 ...
- 【xsy1012】KSHKM的基因工程 AC自动机DP
题目大意:给你$n$个串$p_i$,最后再给一个串$s$(字符集均为A,C,G,T四个字符中的一个).问你串$s$最少要更改多少个字符(更改后的字符也只能是ACGT),才能满足s中不包含$p_i$$( ...
- HDU 4758 Walk Through Squares (2013南京网络赛1011题,AC自动机+DP)
Walk Through Squares Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Oth ...
- HDU2457 DNA repair(AC自动机+DP)
题目一串DNA最少需要修改几个基因使其不包含一些致病DNA片段. 这道题应该是AC自动机+DP的入门题了,有POJ2778基础不难写出来. dp[i][j]表示原DNA前i位(在AC自动机上转移i步) ...
- HDU 2222(AC自动机模板题)
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2222 题目大意:多个模式串.问匹配串中含有多少个模式串.注意模式串有重复,所以要累计重复结果. 解题 ...
- hdu 4117 GRE Words AC自动机DP
题目:给出n个串,问最多能够选出多少个串,使得前面串是后面串的子串(按照输入顺序) 分析: 其实这题是这题SPOJ 7758. Growing Strings AC自动机DP的进阶版本,主题思想差不多 ...
- hdu 2457(ac自动机+dp)
题意:容易理解... 分析:这是一道比较简单的ac自动机+dp的题了,直接上代码. 代码实现: #include<stdio.h> #include<string.h> #in ...
- tyvj P1519 博彩游戏(AC自动机+DP滚动数组)
P1519 博彩游戏 背景 Bob最近迷上了一个博彩游戏…… 描述 这个游戏的规则是这样的:每花一块钱可以得到一个随机数R,花上N块钱就可以得到一个随机序列:有M个序列,如果某个序列是产生的随机序列的 ...
随机推荐
- 猎豹wifi的坑
最近想看看外面的风景,装了Cisco的VPN,但总是连不了外网,国内的网站连接速度比较慢. 运维人员看了很长时间都没发现原因,route print查看之后,说: 在连接外网之前,多走了层路由... ...
- PHP 数组辅助函数
/** * 取多维数据中某字段的值 * @param array $array 数据源数组 * @param string|array $field 要获取的字段 * @return array 结果 ...
- Codeforces 1220D. Alex and Julian
传送门 首先考虑怎样的集合一定是合法的 发现全部是奇数的集合一定合法,因为每次都是奇数连偶数,偶数连奇数 然后考虑如果集合同时有奇数和偶数是否一定不合法,结论是一定不合法,证明如下: 设某个奇数为 $ ...
- ftp安装和虚拟用户创建(终于搞清楚了)
安装 一.安装 sudo apt-get install vsftpd 二.查看安装结果 安装完毕,检查vsftpd进程是否已启动,可以查看进程或者查看监听端口 ps -eaf|grep vsftpd ...
- Oracle及SQLPLUS使用笔记
Oracle及SQLPLUS使用笔记 自己之前粗粗的学过MySQL,学校用的是Oracle,学生使用sqlplus,这是个命令行界面的数据库管理软件(为了学习嘛,不用图形化可以理解),这里记录一些使用 ...
- AWS EC2 搭建 Hadoop 和 Spark 集群
前言 本篇演示如何使用 AWS EC2 云服务搭建集群.当然在只有一台计算机的情况下搭建完全分布式集群,还有另外几种方法:一种是本地搭建多台虚拟机,好处是免费易操控,坏处是虚拟机对宿主机配置要求较高, ...
- 枚举java语言中的修饰符组合
package model; /*22:37 2019/7/20*/ /* top class的修饰符组合 abstract final public 2 * 2 * 2 warning: abstr ...
- redis删除主从节点
1.删除一个Slave节点 ./redis-cli --cluster del-node 127.0.0.1:7001 74957282ffa94c828925c4f7026baac04a67e291 ...
- Django新建第一个投票应用
1:在Pycharm的命令端口,确保执行文件路径是与mysite同级 $ python3 manage.py startapp polls 系统会自动生成polls应用的目录,其结构如下 polls/ ...
- liunx weblogic服务启停脚本
#!/bin/bash #sh xx.sh start xx项目 例如:sh autoWeblogic.sh start bius #经测试发现weblogic 启动大概需要完全启动成功35秒左右 停 ...