HDU - 4758 Walk Through Squares (AC自己主动机+DP)
Description

On the beaming day of 60th anniversary of NJUST, as a military college which was Second Artillery Academy of Harbin Military Engineering Institute before, queue phalanx is a special landscape.
Here is a M*N rectangle, and this one can be divided into M*N squares which are of the same size. As shown in the figure below:
01--02--03--04
|| || || ||
05--06--07--08
|| || || ||
09--10--11--12
Consequently, we have (M+1)*(N+1) nodes, which are all connected to their adjacent nodes. And actual queue phalanx will go along the edges.
The ID of the first node,the one in top-left corner,is 1. And the ID increases line by line first ,and then by column in turn ,as shown in the figure above.
For every node,there are two viable paths:
(1)go downward, indicated by 'D';
(2)go right, indicated by 'R';
The current mission is that, each queue phalanx has to walk from the left-top node No.1 to the right-bottom node whose id is (M+1)*(N+1).
In order to make a more aesthetic marching, each queue phalanx has to conduct two necessary actions. Let's define the action:
An action is started from a node to go for a specified travel mode.
So, two actions must show up in the way from 1 to (M+1)*(N+1).
For example, as to a 3*2 rectangle, figure below:
01--02--03--04
|| || || ||
05--06--07--08
|| || || ||
09--10--11--12
Assume that the two actions are (1)RRD (2)DDR
As a result , there is only one way : RRDDR. Briefly, you can not find another sequence containing these two strings at the same time.
If given the N, M and two actions, can you calculate the total ways of walking from node No.1 to the right-bottom node ?
Input
For each test cases,the first line contains two positive integers M and N(For large test cases,1<=M,N<=100, and for small ones 1<=M,N<=40). M denotes the row number and N denotes the column number.
The next two lines each contains a string which contains only 'R' and 'D'. The length of string will not exceed 100. We ensure there are no empty strings and the two strings are different.
Output
Sample Input
2
3 2
RRD
DDR
3 2
R
D
Sample Output
1
10
题意:给你两串,求用m个R。n个D能组成多少个包括这两个串
思路:先构造一个AC自己主动机记录每一个状态包括两个串的状态,然后利用dp[i][j][k][s]表示i个R,j个D。此时AC自己主动机状态位置到k的时候,状态为s时的个数进行转移
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std;
const int mod = 1e9+7; int dp[110][110][220][4];
int n,m;
int nxt[420][2],fail[420],end[420];
int root,cnt; inline int change(char ch) {
if (ch == 'R')
return 0;
else return 1;
} inline int newNode() {
for (int i = 0; i < 2; i++)
nxt[cnt][i] = -1;
end[cnt++] = 0;
return cnt-1;
} inline void init() {
cnt = 0;
root = newNode();
} inline void insert(char buf[], int id) {
int len = strlen(buf);
int now = root;
for (int i = 0; i < len; i++) {
if (nxt[now][change(buf[i])] == -1)
nxt[now][change(buf[i])] = newNode();
now = nxt[now][change(buf[i])];
}
end[now] |= (1<<id);
} inline void build() {
queue<int> q;
fail[root] = root;
for (int i = 0; i < 2; i++)
if (nxt[root][i] == -1)
nxt[root][i] = root;
else {
fail[nxt[root][i]] = root;
q.push(nxt[root][i]);
} while (!q.empty()) {
int now = q.front();
q.pop();
end[now] |= end[fail[now]];
for (int i = 0; i < 2; i++)
if (nxt[now][i] == -1)
nxt[now][i] = nxt[fail[now]][i];
else {
fail[nxt[now][i]] = nxt[fail[now]][i];
q.push(nxt[now][i]);
}
}
} inline int solve() {
dp[0][0][0][0] = 1;
for (int x = 0; x <= n; x++)
for (int y = 0; y <= m; y++)
for (int i = 0; i < cnt; i++)
for (int k = 0; k < 4; k++) {
if (dp[x][y][i][k] == 0)
continue;
if (x < n) {
int cur = nxt[i][0];
dp[x+1][y][cur][k|end[cur]] += dp[x][y][i][k];
dp[x+1][y][cur][k|end[cur]] %= mod;;
}
if (y < m) {
int cur = nxt[i][1];
dp[x][y+1][cur][k|end[cur]] += dp[x][y][i][k];
dp[x][y+1][cur][k|end[cur]] %= mod;
}
}
int ans = 0;
for (int i = 0; i < cnt; i++) {
ans += dp[n][m][i][3];
ans %= mod;
}
return ans;
} char str[210]; int main() {
int t;
scanf("%d", &t);
while (t--) {
scanf("%d%d", &n, &m);
init();
for (int i = 0; i < 2; i++) {
scanf("%s", str);
insert(str, i);
} build();
for (int i = 0; i <= n; i++)
for (int j = 0; j <= m; j++)
for (int x = 0; x < cnt; x++)
for (int y = 0; y < 4; y++)
dp[i][j][x][y] = 0; printf("%d\n", solve());
}
return 0;
}
HDU - 4758 Walk Through Squares (AC自己主动机+DP)的更多相关文章
- hdu4758 Walk Through Squares (AC自己主动机+DP)
Walk Through Squares Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others ...
- 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 4758 Walk Through Squares ( Trie图 && 状压DP && 数量限制类型 )
题意 : 给出一个 n 行.m 列的方格图,现从图左上角(0, 0) 到右下角的 (n, m)走出一个字符串(规定只能往下或者往右走),向右走代表' R ' 向下走则是代表 ' D ' 最后从左上角到 ...
- HDU 4758 Walk Through Squares(AC自动机+DP)
题目链接 难得出一个AC自动机,我还没做到这个题呢...这题思路不难想,小小的状压出一维来,不过,D和R,让我wa死了,AC自动机,还得刷啊... #include<iostream> # ...
- HDU - 2825 Wireless Password(AC自己主动机+DP)
Description Liyuan lives in a old apartment. One day, he suddenly found that there was a wireless ne ...
- Hdu 3341 Lost's revenge (ac+自己主动机dp+hash)
标题效果: 举个很多种DNA弦,每个字符串值值至1.最后,一个长字符串.要安排你最后一次另一个字符串,使其没事子值和最大. IDEAS: 首先easy我们的想法是想搜索的!管她3721..直接一个字符 ...
- 【HDU 5384】Danganronpa(AC自己主动机)
看官方题解貌似就是个自己主动机裸题 比赛的时候用kuangbin的AC自己主动机模板瞎搞的,居然A了,并且跑的还不慢.. 存下模板吧 #include<cstdio> #include&l ...
- HDU 3247 Resource Archiver (AC自己主动机 + BFS + 状态压缩DP)
题目链接:Resource Archiver 解析:n个正常的串.m个病毒串,问包括全部正常串(可重叠)且不包括不论什么病毒串的字符串的最小长度为多少. AC自己主动机 + bfs + 状态压缩DP ...
- HDU 2222 Keywords Search(AC自己主动机模板题)
题意:给出一个字符串和若干个模板,求出在文本串中出现的模板个数. 思路:由于有可能有反复的模板,trie树权值记录每一个模板出现的次数就可以. #include<cstdio> #incl ...
随机推荐
- JavaScript 中对变量和函数声明提前的演示样例
如题所看到的,看以下的演示样例(能够使用Chrome浏览器,然后F12/或者右键,审查元素.调出开发人员工具,进入控制台console输入)(使用技巧: 控制台输入时Shift+Enter能够中途代码 ...
- Django -> debug模式下的静态文件服务(/media/)
正式公布django项目的时候,假设存在静态文件(通常会统一放在名称为media或static的文件夹下),则须要建立url到文件系统的映射,比如.使用nginx的时候我们须要进行这种配置. # Dj ...
- HDU 4912 lca贪心
Paths on the tree Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Othe ...
- c3---scanf
#include <stdio.h> int main(int argc, const char * argv[]) { // 要求: 存储用户输入的整数 // 1.用户输入的整数确定吗? ...
- java.io.IOException: Cannot find any registered HttpDestinationFactory from the Bus.
转自:https://blog.csdn.net/u012849872/article/details/51037374
- Navicat 连接 Mysql 报2059错误的原因以及解决方法
MySQL的8.0.*版本使用的是caching_sha2_password验证方式,而Navicat Premium 12还不支持该种方式.解决方案: 1,降低mysql的版本 2,设置mysql支 ...
- 了解和解决SQL SERVER阻塞问题(copy)
http://support.microsoft.com/kb/224453 Summary In this article, the term "connection" refe ...
- 【转】SQL Server 2008 数据库同步的两种方式 (发布、订阅)
上篇中说了通过SQL JOB的方式对数据库的同步,这一节作为上一节的延续介绍通过发布订阅的方式实现数据库之间的同步操作.发布订阅份为两个步骤:1.发布.2.订阅.首先在数据源数据库服务器上对需要同步的 ...
- 远程桌面连接Windows Azure中的Ubuntu虚拟机
默认情况下,通过Windows Azure创建的ubuntu虚拟机是不能直接连接远程桌面的,只能通过SSH终端连接. 在Windows Azure Portal中创建Ubuntu虚拟机,创建完成后添加 ...
- redis的持久化功能
基于快照持久化 修改配置文件,开始基于快照的选项 [root@localhostbin]#vim /etc/redis/redis.conf stop-writes-on-bgsave-error y ...