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/Others)
Total Submission(s): 200 Accepted Submission(s): 57

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
太伤了。
网络赛的时候没有过这题,都写对了,就是一直WA
比赛结束后问了下世界冠军cxlove,看了一眼发现是建立AC自动机的时候,fail的end要传递下,加一句话就过了,TAT
使用AC自动机+DP。
dp[x][y][i][k] 四维DP,表示R的个数是x,D的个数是y, i是在AC自动机上的节点编号。k 是状态压缩。
/* ***********************************************
Author :kuangbin
Created Time :2013/9/21 星期六 15:57:51
File Name :2013南京网络赛\1011.cpp
************************************************ */ #pragma comment(linker, "/STACK:1024000000,1024000000")
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
using namespace std;
const int MOD = 1e9+; int dp[][][][];
int n,m;
//struct Trie
//{
int next[][],fail[],end[];
int root,L;
inline int change(char ch)
{
if(ch == 'R')return ;
else return ;
}
inline int newnode()
{
for(int i = ;i < ;i++)
next[L][i] = -;
end[L++] = ;
return L-;
}
inline void init()
{
L = ;
root = newnode();
}
inline void insert(char buf[],int id)
{
int len = strlen(buf);
int now = root;
for(int i = ;i < len;i++)
{
if(next[now][change(buf[i])] == -)
next[now][change(buf[i])] = newnode();
now = next[now][change(buf[i])];
}
end[now] |= (<<id);
}
inline void build()
{
queue<int>Q;
fail[root] = root;
for(int i = ;i < ;i++)
if(next[root][i] == -)
next[root][i] = root;
else
{
fail[next[root][i]] = root;
Q.push(next[root][i]);
}
while( !Q.empty() )
{
int now = Q.front();
Q.pop();
end[now] |= end[fail[now]];
for(int i = ;i < ;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]);
}
}
}
inline int solve()
{
dp[][][][] = ;
int ret = ; for(int x = ;x <= n;x++)
for(int y = ;y <= m;y++)
for(int i = ;i < L;i++) for(int k = ;k < ;k++) {
if(dp[x][y][i][k] == )continue;
if(x < n)
{
int nxt = next[i][];
dp[x+][y][nxt][k|end[nxt]] += dp[x][y][i][k];
if(dp[x+][y][nxt][k|end[nxt]] >= MOD)
dp[x+][y][nxt][k|end[nxt]] -= MOD;
}
if(y < m)
{
int nxt = next[i][];
dp[x][y+][nxt][k|end[nxt]] += dp[x][y][i][k];
if(dp[x][y+][nxt][k|end[nxt]] >= MOD)
dp[x][y+][nxt][k|end[nxt]] -= MOD;
}
}
for(int i = ;i < L;i++)
{
ret += dp[n][m][i][];
if(ret >= MOD)ret -= MOD;
} return ret; }
//};
//Trie ac;
char str[]; int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
init();
for(int i = ;i < ;i++)
{
scanf("%s",str);
insert(str,i);
}
build();
for(int i = ;i <= n;i++)
for(int j = ;j <= m;j++)
for(int x = ; x < L;x++)
for(int y = ;y < ;y++)
dp[i][j][x][y] = ;
printf("%d\n",solve());
}
return ;
}
HDU 4758 Walk Through Squares (2013南京网络赛1011题,AC自动机+DP)的更多相关文章
- HDU 4751 Divide Groups (2013南京网络赛1004题,判断二分图)
Divide Groups Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Tot ...
- HDU 4750 Count The Pairs (2013南京网络赛1003题,并查集)
Count The Pairs Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others ...
- HDU 4758——Walk Through Squares——2013 ACM/ICPC Asia Regional Nanjing Online
与其说这是一次重温AC自动机+dp,倒不如说这是个坑,而且把队友给深坑了. 这个题目都没A得出来,我只觉得我以前的AC自动机的题目都白刷了——深坑啊. 题目的意思是给你两个串,每个串只含有R或者D,要 ...
- HDU 4759 Poker Shuffle(2013长春网络赛1001题)
Poker Shuffle Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Tot ...
- hdu 4750 Count The Pairs (2013南京网络赛)
n个点m条无向边的图,对于q个询问,每次查询点对间最小瓶颈路 >=f 的点对有多少. 最小瓶颈路显然在kruskal求得的MST上.而输入保证所有边权唯一,也就是说f[i][j]肯定唯一了. 拿 ...
- 2019ICPC南京网络赛A题 The beautiful values of the palace(三维偏序)
2019ICPC南京网络赛A题 The beautiful values of the palace https://nanti.jisuanke.com/t/41298 Here is a squa ...
- HDU 4739 Zhuge Liang's Mines (2013杭州网络赛1002题)
Zhuge Liang's Mines Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Othe ...
- HDU 4763 Theme Section (2013长春网络赛1005,KMP)
Theme Section Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Tot ...
- HDU 4762 Cut the Cake (2013长春网络赛1004题,公式题)
Cut the Cake Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Tota ...
随机推荐
- AngularJS入门基础——表单验证
<form name="form" novalidata> <label name="email">your email</l ...
- Android的layout_weight和weightSum
先看一下weightSum属性的功能描述:定义weight总和的最大值.如果未指定该值,以所有子视图的layout_weight属性的累加值作为总和的最大值.把weightSum的定义搁在这里,先去看 ...
- mybatis一对一关联查询——(八)
1.需求 查询所有订单信息,关联查询下单用户信息. 注意: 因为一个订单信息只会是一个人下的订单,所以从查询订单信息出发关联查询用户信息为一对一查询.如果从用户信息出发查询用户下的订单信息则为一对多查 ...
- phantomjs waitFor
function waitFor(testFx, onReady, timeOutMillis) { var maxtimeOutMillis = timeOutMillis ? timeOutMil ...
- 微信小程序调用接口返回数据或提交数据
由于小程序发起网络请求需要通过 wx.request 文档地址 https://mp.weixin.qq.com/debug/wxadoc/dev/api/network-request.html 习 ...
- poj1679
题意:给定一个无向连通图,问该图的最小生成树是否唯一. 分析:有一个定理,如果该图存在次小生成树(与原最小生成树不同,但长度小于等于原最小生成树),则一定可以通过从原最小生成树中去掉一个边并再入一个边 ...
- jenkins+jmeter结合使用
事件背景:想实现jmeter每30分钟执行一次,但是夜里不能人工操作,结果度娘,汇总结果如下 1.配置jmeter测试环境,注意修改Jmeter的bin目录下jmeter.properties文件的配 ...
- kafka脚本
为了便于使用,kafka提供了比较强大的Tools,把经常需要使用的整理一下 开关kafka Server bin/kafka-server-start.sh config/server.proper ...
- C++学习笔记(原创)
以下内容为自己一年多的C++学习心得,纯原创,转载请注明源地址. 一年多的C++学习过程中,自己阅读了很多C++经典著作,有<effective c++>,<more effecti ...
- csu 1982:小M的移动硬盘(双向链表)
Description 最近小M买了一个移动硬盘来储存自己电脑里不常用的文件.但是他把这些文件一股脑丢进移动硬盘后,觉得这些文件似乎没有被很好地归类,这样以后找起来岂不是会非常麻烦? 小M最终决定要把 ...