hdu4758 Walk Through Squares
地址:http://acm.split.hdu.edu.cn/showproblem.php?pid=4758
题目:
Walk Through Squares
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others)
Total Submission(s): 1548 Accepted Submission(s): 514
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 ?
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.
3 2
RRD
DDR
3 2
R
D
10
#include <queue>
#include <cstring>
#include <cstdio>
using namespace std; const int mod = 1e9 + ;
struct AC_auto
{
const static int LetterSize = ;
const static int TrieSize = * ( 4e2 + ); int tot,root,fail[TrieSize],end[TrieSize],next[TrieSize][LetterSize];
int dp[][TrieSize][][]; int newnode(void)
{
memset(next[tot],-,sizeof(next[tot]));
end[tot] = ;
return tot++;
} void init(void)
{
tot = ;
root = newnode();
} int getidx(char x)
{
return x=='R';
} void insert(char *ss,int id)
{
int len = strlen(ss);
int now = root;
for(int i = ; i < len; i++)
{
int idx = getidx(ss[i]);
if(next[now][idx] == -)
next[now][idx] = newnode();
now = next[now][idx];
}
end[now]|=id;
} void build(void)
{
queue<int>Q;
fail[root] = root;
for(int i = ; i < LetterSize; i++)
if(next[root][i] == -)
next[root][i] = root;
else
fail[next[root][i]] = root,Q.push(next[root][i]);
while(Q.size())
{
int now = Q.front();Q.pop();
for(int i = ; i < LetterSize; i++)
if(next[now][i] == -) next[now][i] = next[fail[now]][i];
else
fail[next[now][i]] = next[fail[now]][i],Q.push(next[now][i]),end[next[now][i]]|=end[next[fail[now]][i]];
}
} int match(char *ss)
{
int len,now,res;
len = strlen(ss),now = root,res = ;
for(int i = ; i < len; i++)
{
int idx = getidx(ss[i]);
int tmp = now = next[now][idx];
while(tmp)
{
res += end[tmp];
end[tmp] = ;//按题目修改
tmp = fail[tmp];
}
}
return res;
} void go(int n,int m)
{
//debug();
int now=;
memset(dp[],,sizeof dp[]);
dp[][][][]=;
for(int p=;p<n+m;p++)
{
memset(dp[now],,sizeof dp[now]);
for(int i=;i<tot;i++)
for(int x=;x<=n;x++)
for(int k=;k<&&x<=p&&p-x<=m;k++)
if(dp[now^][i][x][k])
{
if(x!=n)
{
int nt=next[i][],st=end[nt]|k;
dp[now][nt][x+][st] = (dp[now][nt][x+][st] + dp[now^][i][x][k] ) % mod;
}
if(p-x!=m)
{
int nt=next[i][],st=end[nt]|k;
dp[now][nt][x][st] = (dp[now][nt][x][st] + dp[now^][i][x][k] ) % mod;
}
}
// printf("=======\n");
// for(int i=0;i<tot;i++)
// for(int x=0;x<=n&&x<=p+1&&p+1-x<=m;x++)
// for(int k=0;k<4;k++)
// printf("%d %d %d %d :%d\n",now,i,x,k,dp[now][i][x][k]);
now^=;
}
int ans=;
for(int i=;i<tot;i++)
ans=(ans+dp[now^][i][n][])%mod;
printf("%d\n",ans);
}
void debug()
{
for(int i = ;i < tot;i++)
{
printf("id = %3d,fail = %3d,end = %3d,chi = [",i,fail[i],end[i]);
for(int j = ;j < LetterSize;j++)
printf("%3d",next[i][j]);
printf("]\n");
}
}
}ac;
char ss[];
int main(void)
{
int t,n,m;
scanf("%d",&t);
while(t--)
{
scanf("%d%d%s",&m,&n,ss);
ac.init();
ac.insert(ss,);
scanf("%s",ss);
ac.insert(ss,);
ac.build();
ac.go(n,m);
}
return ;
}
hdu4758 Walk Through Squares的更多相关文章
- hdu4758 Walk Through Squares (AC自己主动机+DP)
Walk Through Squares Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others ...
- HDU4758 Walk Through Squares(AC自动机+状压DP)
题目大概说有个n×m的格子,有两种走法,每种走法都是一个包含D或R的序列,D表示向下走R表示向右走.问从左上角走到右下角的走法有多少种走法包含那两种走法. D要走n次,R要走m次,容易想到用AC自动机 ...
- HDU4758 Walk Through Squares AC自动机&&dp
这道题当时做的时候觉得是数论题,包含两个01串什么的,但是算重复的时候又很蛋疼,赛后听说是字符串,然后就觉得很有可能.昨天队友问到这一题,在学了AC自动机之后就觉得简单了许多.那个时候不懂AC自动机, ...
- hdu4758 Walk Through Squares 自动机+DP
题意:给n*m的地图,在地图的点上走,(n+1)*(m+1)个点,两种操作:往下走D和往右走R.现在要从左上角走到右下角,给定两个操作串,问包含这两个串的走法总共有多少种. 做法:用这两个串构建自动机 ...
- 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 ...
- 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)
题目链接 难得出一个AC自动机,我还没做到这个题呢...这题思路不难想,小小的状压出一维来,不过,D和R,让我wa死了,AC自动机,还得刷啊... #include<iostream> # ...
- hdu 4758 Walk Through Squares
AC自动机+DP.想了很久都没想出来...据说是一道很模板的自动机dp...原来自动机还可以这么跑啊...我们先用两个字符串建自动机,然后就是建一个满足能够从左上角到右下角的新串,这样我们直接从自动机 ...
- HDU 4758——Walk Through Squares——2013 ACM/ICPC Asia Regional Nanjing Online
与其说这是一次重温AC自动机+dp,倒不如说这是个坑,而且把队友给深坑了. 这个题目都没A得出来,我只觉得我以前的AC自动机的题目都白刷了——深坑啊. 题目的意思是给你两个串,每个串只含有R或者D,要 ...
随机推荐
- docker学习-docker解决了什么问题
docker标准化让快速扩张.弹性伸缩变得简答.
- Python 入门(十)列表生成式
生成列表 要生成list [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],我们可以用range(1, 11): >>> range(1, 11) [1, 2, 3, ...
- Linux tty 命令
终端:终端(Terminal)也称终端设备,是计算机网络中处于网络最外围的设备(如键盘 .打印机 .显示器等),主要用于用户信息的输入以及处理结果的输出 TTY:TTY 是 Teletype(电传打字 ...
- Memcache命令及参数用法
Memcache命令:在linux下: # /usr/local/bin/memcached -d -m 128 -u root -l 192.168.0.10 -p 12121 -c 256 -P ...
- php学习十三:其他关键字
在php中,其实不止在php中,在其他语言中我们也会常常接触到一些关键字,整理了一下php当中的一下关键字,可能有些不全,希望大家指出来,多多交流,一起进步. 1.final 特性:1.使用final ...
- PHP MySQL Insert Into
INSERT INTO 语句用于向数据库表中插入新记录. 向数据库表插入数据 INSERT INTO 语句用于向数据库表添加新记录. 语法 INSERT INTO table_name VALUES ...
- salt-stack更换主机名
author:headsen chen date: 2018-09-30 11:22:40 1,建立master端和client端的正常连接 #master yum -y install epel ...
- 移动端开发--rem和像素如何使用!
刚开始做移动端的开发的时候,大多时候是在使用 像素(PX)来写页面和布局的,但是使用下来,还是有多少不好用! 随之就开始用 rem 来写,rem写的结果是页面放到一些屏幕上,字体过小,如果页面渲染用了 ...
- EDT改成CST
功能说明:显示文字.语 法:echo [-ne][字符串]或 echo [--help][--version]补充说明:echo会将输入的字符串送往标准输出.输出的字符串间以空白字符隔开, 并在最后加 ...
- LISTAGG
LISTAGG(measure_expr [, 'delimiter']) WITHIN GROUP (order_by_clause) [OVER query_partition_clause] S ...