(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)的更多相关文章

  1. 对AC自动机+DP题的一些汇总与一丝总结 (2)

    POJ 2778 DNA Sequence (1)题意 : 给出m个病毒串,问你由ATGC构成的长度为 n 且不包含这些病毒串的个数有多少个 关键字眼:不包含,个数,长度 DP[i][j] : 表示长 ...

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

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

  3. 【xsy1012】KSHKM的基因工程 AC自动机DP

    题目大意:给你$n$个串$p_i$,最后再给一个串$s$(字符集均为A,C,G,T四个字符中的一个).问你串$s$最少要更改多少个字符(更改后的字符也只能是ACGT),才能满足s中不包含$p_i$$( ...

  4. 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 ...

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

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

  6. HDU 2222(AC自动机模板题)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2222 题目大意:多个模式串.问匹配串中含有多少个模式串.注意模式串有重复,所以要累计重复结果. 解题 ...

  7. hdu 4117 GRE Words AC自动机DP

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

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

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

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

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

随机推荐

  1. Mysql 事件记录 | performance_schema全方位介绍

    Mysql 事件记录 | performance_schema全方位介绍 | 导语 在上一篇 初相识|performance_schema全方位介绍 中,我们详细介绍了performance_sche ...

  2. redis为什么使用单线程 ,还那么快,单线程是怎么实现的

    单线程使用队列 为什么使用单线程 https://baijiahao.baidu.com/s?id=1628498089535886382&wfr=spider&for=pc http ...

  3. 深入理解java虚拟机(3)垃圾收集器与内存分配策略

    一.根搜索算法: (1)定义:通过一系列名为"GC Roots"的对象作为起点,从这些起点开始向下搜索,搜索走过的路径称为引用链,当一个对象到GC Roots没有任何引用链相连的时 ...

  4. Android 关于悬浮窗权限的问题

    正常情况下的处理: dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT)以及在清单文件中添加 <use ...

  5. 爬虫之request相关请求

    一.解析json格式数据 (1) # (1)解析json 对象数据 # import requests # 返回的数据进行解析 # response = requests.get('http://ht ...

  6. GDAL支持中文路径和Shp文件中文属性写入

    在使用GDAL的过程中,为了支持中文,比需手动进行中文路径的设置,同时特别是在对Shp的属性进行中文输入的时候,都必须进行必要的设定. 为了支持中文路径,在注册了驱动之后,加上第三句就可以了.必须设置 ...

  7. python自动化测试—配置文件的使用

    一.什么是配置文件? 配置文件示例 [mysql] default-character-set = utf8 [mysqld] port = 3306 basedir = c:\mysql-5.7.2 ...

  8. oracle的sql 记录

    ----1.分组函数--select max(tfi.expected_scale) max1,min(tfi.expected_scale) min1,to_char(avg(tfi.expecte ...

  9. 绕过CDN找到真实IP

    现在很多大型企业都会使用CDN内容分发网络,因为CDN存在多个缓存服务点,而且会根据用户IP地址,将用户请求导向到最近的服务点上进行相应,所以得不到主服务站点的ip地址,总结学习一下绕过CDN找到真实 ...

  10. Ubuntu 16.04 编译ORB_SLAM2_modified

    编译g2o_with_orbslam2 1.修改g2o/types/slam2d/edge_se2_pointxy_bearing.cpp t.setRotation(t.rotation().ang ...