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

  The first line contains a number T,(T is about 100, including 90 small test cases and 10 large ones) denoting the number of the test cases.


  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

  For each test cases,print the answer MOD 1000000007 in one line.

 

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

  1. hdu4758 Walk Through Squares (AC自己主动机+DP)

    Walk Through Squares Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others ...

  2. 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,在自动机中的状态 ...

  3. HDU 4758 Walk Through Squares ( Trie图 && 状压DP && 数量限制类型 )

    题意 : 给出一个 n 行.m 列的方格图,现从图左上角(0, 0) 到右下角的 (n, m)走出一个字符串(规定只能往下或者往右走),向右走代表' R ' 向下走则是代表 ' D ' 最后从左上角到 ...

  4. HDU 4758 Walk Through Squares(AC自动机+DP)

    题目链接 难得出一个AC自动机,我还没做到这个题呢...这题思路不难想,小小的状压出一维来,不过,D和R,让我wa死了,AC自动机,还得刷啊... #include<iostream> # ...

  5. HDU - 2825 Wireless Password(AC自己主动机+DP)

    Description Liyuan lives in a old apartment. One day, he suddenly found that there was a wireless ne ...

  6. Hdu 3341 Lost&#39;s revenge (ac+自己主动机dp+hash)

    标题效果: 举个很多种DNA弦,每个字符串值值至1.最后,一个长字符串.要安排你最后一次另一个字符串,使其没事子值和最大. IDEAS: 首先easy我们的想法是想搜索的!管她3721..直接一个字符 ...

  7. 【HDU 5384】Danganronpa(AC自己主动机)

    看官方题解貌似就是个自己主动机裸题 比赛的时候用kuangbin的AC自己主动机模板瞎搞的,居然A了,并且跑的还不慢.. 存下模板吧 #include<cstdio> #include&l ...

  8. HDU 3247 Resource Archiver (AC自己主动机 + BFS + 状态压缩DP)

    题目链接:Resource Archiver 解析:n个正常的串.m个病毒串,问包括全部正常串(可重叠)且不包括不论什么病毒串的字符串的最小长度为多少. AC自己主动机 + bfs + 状态压缩DP ...

  9. HDU 2222 Keywords Search(AC自己主动机模板题)

    题意:给出一个字符串和若干个模板,求出在文本串中出现的模板个数. 思路:由于有可能有反复的模板,trie树权值记录每一个模板出现的次数就可以. #include<cstdio> #incl ...

随机推荐

  1. 用友ERP T6技术解析(六) 库龄分析

    2.4 库存管理   2.4.1 库龄分析 介绍:库存账龄是在某时间节点,某种或某类存货的库存时间的加权平均值,跟库存周转率关系明显,库存周转率越高,库存账龄越低,可是二者又不是反比关系.不能简单把库 ...

  2. 虚拟ONVIF 摄像机

    測试视频监控系统须要大量的Camera.搭建起来也很麻烦,在vdceye中增加虚拟onvif 摄像 机支持,把一个Camera变成上百个. watermark/2/text/aHR0cDovL2Jsb ...

  3. Redis源代码分析(二十二)--- networking网络协议传输

    上次我仅仅分析了Redis网络部分的代码一部分,今天我把networking的代码实现部分也学习了一遍,netWorking的代码很多其它偏重的是Clientclient的操作.里面addReply( ...

  4. Gzip压缩优化网站

    网站常使用GZIP压缩算法对网页内容进行压缩,然后传给浏览器,以减小数据传输量,提高响应速度.浏览器接收到GZIP压缩数据后会自动解压并正确显示.GZIP加速常用于解决网速慢的瓶颈. 压缩Filter ...

  5. 英语发音规则---X字母

    英语发音规则---X字母 一.总结 一句话总结: 1.x位于词尾或音节尾部,读/ks/? box /bɒks/ n.盒; 箱状物 fix /fɪks/ vt.固定 fox /fɒks/ n.狐; 狐狸 ...

  6. phpmyadmin客户端多服务器配置

    修改libraries/config.default.php 545行,添加 $cfg['Servers']['2'] = $cfg['Servers'][$i];$cfg['Servers']['2 ...

  7. Oracle SQL性能优化系列

    1. 选用适合的ORACLE优化器 ORACLE的优化器共有3种: a. RULE (基于规则) b. COST (基于成本) c. CHOOSE (选择性) 设置缺省的优化器,可以通过对init.o ...

  8. Extjs Grid 各种Demo

    grid的一个渲染效果 Ext.define('cfWeb.view.accountSetting.OrgManageView',{ alias : 'widget.orgManageView', e ...

  9. 基于Redis实现分布式应用限流--转

    原文地址:https://my.oschina.net/giegie/blog/1525931 摘要: 限流的目的是通过对并发访问/请求进行限速或者一个时间窗口内的的请求进行限速来保护系统,一旦达到限 ...

  10. Oprofile分析(android oprofile性能分析)

    一.内核支持: make menuconfig 1.评测菜单中启用 Oprofile ,在 .config 文件中设置?CONFIG_PROFILING=y?和?CONFIG_OPROFILE=y 2 ...