HDU 4758 Walk Through Squares ( Trie图 && 状压DP && 数量限制类型 )
题意 : 给出一个 n 行、m 列的方格图,现从图左上角(0, 0) 到右下角的 (n, m)走出一个字符串(规定只能往下或者往右走),向右走代表' R ' 向下走则是代表 ' D ' 最后从左上角到右下角,不同的路线会走出不同的字符串,问你这些不同的字符串有多少个是包含了接下来给定的两个子串。
分析 : 简单想想不难发现最后肯定是走了 (n+1) 个 ' D ' 和 (m+1)个 ' R ' ,那么也就是说用 (n+1) 个 ' D ' 和 (m+1)个 ' R ' 构造出长度为 (n+m+2) 的字符串,且包含给定的两个子串的方案数有多少个( 跟 HDU 3341 类似 ),那么来看看关键点,即考虑 ' D '与' R '的数量、以及当前节点包含了多少个子串、当前停留在Trie上哪个节点,那么可以定义出DP[i][j][k][l]代表在有 i 个 ' D '(即向下走了 i 步)、j 个 ' R '(向右走 j 步)、停留在 k 这个节点、包含子串情况 l 时的最大方案数,则状态转移方程为
每个节点能向 ' D ' 和 ' R ' 转移,这里以向 ' D ' 转移为例
DP[i+1][j][k][l | Trie[k]['D'].id] += DP[i][j][k][l] ( Trie[k]['D']代表从 k 转移到状态为' D '节点,其 id 表示包含字母的情况 )
DP初始状态为 DP[0][0][0][0] = 1、DP其他 = 0
#include<bits/stdc++.h> using namespace std; ; ; ; int n, m; ][][][]; struct Aho{ struct StateTable{ int Next[Letter]; int fail, id; }Node[Max_Tot]; int Size; queue<int> que; inline void init(){ while(!que.empty()) que.pop(); memset(Node[].Next, , ].Next)); Node[].fail = Node[].id = ; Size = ; } inline void insert(char *s, int id){ ; ; s[i]; i++){ int idx = (s[i] == 'D'); if(!Node[now].Next[idx]){ memset(Node[Size].Next, , sizeof(Node[Size].Next)); Node[Size].fail = Node[Size].id = ; Node[now].Next[idx] = Size++; } now = Node[now].Next[idx]; } Node[now].id |= (<<id); } inline void BuildFail(){ Node[].fail = ; ; i<Letter; i++){ ].Next[i]){ Node[Node[].Next[i]].fail = ; que.push(Node[].Next[i]); }].Next[i] = ; } while(!que.empty()){ int top = que.front(); que.pop(); Node[top].id |= Node[Node[top].fail].id; ; i<Letter; i++){ int &v = Node[top].Next[i]; if(v){ que.push(v); Node[v].fail = Node[Node[top].fail].Next[i]; }else v = Node[Node[top].fail].Next[i]; } } } }ac; int Solve() { ; i<=n; i++) ; j<=m; j++) ; k<ac.Size; k++) ; l<; l++) dp[i][j][k][l] = ; dp[][][][] = ; ; i<=n; i++){ ; j<=m; j++){ ; k<ac.Size; k++){ ; l<; l++){ ){ ]; ]; 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; } } } } } ; ; i<ac.Size; i++){ ans += dp[n][m][i][]; ans %= MOD; } return ans%MOD; } ]; int main(void) { int nCase; scanf("%d", &nCase); while(nCase--){ scanf("%d %d", &m, &n); ac.init(); ; i<; i++){ scanf("%s", S); ac.insert(S, i); }ac.BuildFail(); printf("%d\n", Solve()); } ; }
HDU 4758 Walk Through Squares ( Trie图 && 状压DP && 数量限制类型 )的更多相关文章
- HDU 3341 Lost's revenge ( Trie图 && 状压DP && 数量限制类型 )
题意 : 给出 n 个模式串,最后给出一个主串,问你主串打乱重组的情况下,最多能够包含多少个模式串. 分析 : 如果你做过类似 Trie图 || AC自动机 + DP 类似的题目的话,那么这道题相对之 ...
- HDU - 4758 Walk Through Squares (AC自己主动机+DP)
Description On the beaming day of 60th anniversary of NJUST, as a military college which was Secon ...
- HDU 4758 Walk Through Squares( AC自动机 + 状态压缩DP )
题意:给你两个串A,B, 问一个串长为M+N且包含A和B且恰好包含M个R的字符串有多少种组合方式,所有字符串中均只含有字符L和R. dp[i][j][k][S]表示串长为i,有j个R,在自动机中的状态 ...
- HDU 3920Clear All of Them I(状压DP)
HDU 3920 Clear All of Them I 题目是说有2n个敌人,现在可以发n枚炮弹,每枚炮弹可以(可以且仅可以)打两个敌人,每一枚炮弹的花费等于它所行进的距离,现在要消灭所有的敌人 ...
- HDU 5067 Harry And Dig Machine(状压dp)
HDU 5067 Harry And Dig Machine 思路:因为点才10个,在加上一个起点,处理出每一个点之间的曼哈顿距离,然后用状压dp搞,状态表示为: dp[i][s],表示在i位置.走过 ...
- HDU 3247 Resource Archiver(AC自动机 + 状压DP + bfs预处理)题解
题意:目标串n( <= 10)个,病毒串m( < 1000)个,问包含所有目标串无病毒串的最小长度 思路:貌似是个简单的状压DP + AC自动机,但是发现dp[1 << n][ ...
- HDU - 6125: Free from square (状压DP+分组背包)
problem:给定N,K.表示你有数1到N,让你最多选择K个数,问有多少种方案,使得选择的数的乘积无平方因子数.N,K<500: solution:显然可以状压DP做,但是500以内的素数还是 ...
- HDU 6984 - Tree Planting(数据分治+状压 dp)
题面传送门 傻逼卡常屑题/bs/bs,大概现场过得人比较少的原因就是它比较卡常罢(Fog 首先对于这样的题我们很难直接维护,不过注意到这个 \(n=300\) 给得很灵性,\(k\) 比较小和 \(k ...
- 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 ...
随机推荐
- MySQL学习-入门语句以及增删查改
1. SQL入门语句 SQL,指结构化查询语言,全称是 Structured Query Language,是一种 ANSI(American National Standards Institute ...
- 利用coverage工具进行Python代码覆盖率测试
Coverage是一种用于统计Python代码覆盖率的工具,通过它可以检测测试代码对被测代码的覆盖率情况. Coverage安装 1.安装命令:pip install coverage 2.查看cov ...
- 使用Dockerfile制作镜像
组成部分 基础镜像信息 FROM 维护者信息 MAINTAINER.LABEL 镜像操作指令 RUN.COPY.ADD.EXPOSE.WORKDIR.ONBUILD.US ...
- javascript 异常处理
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...
- spring -boot定时任务 quartz 基于 MethodInvokingJobDetailFactoryBean 实现
spring 定时任务 quartz 基于 MethodInvokingJobDetailFactoryBean 实现 依赖包 如下 <dependencies> <depende ...
- java锁的使用
1 synchronize和ReentrantLock synchronize锁是jvm内置的锁,它锁的是synchronize所在的类的对象,要同步那么就只能有一个对象. ReentrantLock ...
- Linux cat 多行写入文件防止变量替换
Linux cat 多行写入文件防止变量替换 问题描述 对多个变量及多行输出到文件,存在变量自动替换,当使用cat<<EOF不想对内容进行变量替换.命令替换.参数展开等 问题解决 转义特 ...
- UUID与System.currentTimeMillis()产生一个新文件名的工具类
1.FileUtils.java package Utils.GenerateNewFileName; import java.util.UUID; public class FileUtils { ...
- python字符串 常用函数 格式化字符串 字符串替换 制表符 换行符 删除空白 国际货币格式
# 字符串常用函数# 转大写print('bmw'.upper()) # BMW# 转小写print('BMW'.lower()) # bmw# 首字母大写print('how aae you ?'. ...
- SCUT - 482 - 生成树上的点 - Prufer
https://scut.online/p/482 没听说过这个东西. 洛谷也有这个,所以还是要去接触一些奇奇怪怪的知识才行. https://www.luogu.org/problem/P2290 ...