题意:给n*m的地图,在地图的点上走,(n+1)*(m+1)个点,两种操作:往下走D和往右走R。现在要从左上角走到右下角,给定两个操作串,问包含这两个串的走法总共有多少种。

做法:用这两个串构建自动机,然后只要在自动机上走n+m+1步就好了。就像一个递推,dp[x][y][i][cur]表示在i状态到达x,y坐标时走过的串的状态为cur时的总方案数

我和我的小伙伴们都弱爆了。

为什么没写过就不敢写。

这几天看自动机应该也看会了吧。

#define mod 1000000007

int f[][][][] ;
int hash[];
int n,m;
struct ACmation {
static const int UNDEF = ;
static const int MAXN = ;
static const int CHARSET = ; int end;
int count[MAXN];
int fail[MAXN];
int ch[MAXN][CHARSET]; void init() {
count[] = UNDEF;
fill(ch[], ch[] + CHARSET, -);
end = ;
} void add(int m, const int* s, int t) {
int p = ;
for (int i = ; i < m; ++i) {
if (ch[p][*s] == -) {
count[end] = UNDEF;
fill(ch[end], ch[end] + CHARSET, -);
ch[p][*s] = end++;
}
p = ch[p][*s];
++s;
}
count[p] |= t;
} void build() {
queue<int> bfs;
fail[] = ;
for (int i = ; i < CHARSET; ++i) {
if (ch[][i] != -) {
fail[ch[][i]] = ;
bfs.push(ch[][i]);
} else {
ch[][i] = ;
}
}
while (!bfs.empty()) {
int p = bfs.front();
count[p] |= count[fail[p]];
bfs.pop();
for (int i = ; i < CHARSET; ++i) {
if (ch[p][i] != -) {
fail[ch[p][i]] = ch[fail[p]][i];
bfs.push(ch[p][i]);
} else {
ch[p][i] = ch[fail[p]][i];
}
}
}
}
int solve()
{
memset(f,,sizeof(f));
f[][][count[]][] = ;
int tmp ;
for(int x = ; x <= n ; x ++ )
{
for(int y = ; y <= m; y ++ )
{
for(int i = ; i < end; i ++ )
{
for(int cur = ; cur < ; cur ++ )
{
//printf("count[i] = %d\n",count[i]);
if(x + <= n )
{
tmp = cur | count[ch[i][]];
f[x+][y][ch[i][]][tmp] = (f[x][y][i][cur] + f[x+][y][ch[i][]][tmp] ) % mod;
// printf("%d %d %d %d %d\n",x+1,y,ch[i][0],tmp,f[x+1][y][ch[i][0]][tmp]);
}
if(y + <= m )
{
tmp = cur | count[ch[i][]];
f[x][y+][ch[i][]][tmp] = (f[x][y][i][cur] + f[x][y+][ch[i][]][tmp] ) % mod;
//printf("%d %d %d %d %d\n",x,y+1,ch[i][0],tmp,f[x][y+1][ch[i][0]][tmp]);
}
}
}
}
}
int res;
res = ;
for(int i = ; i < end ; i ++ )
{
res = (f[n][m][i][] + res) % mod ;
}
return res % mod ;
}
} ac;
char str[];
int len ;
int te[];
int main()
{
int cas;
memset(hash,-,sizeof(hash));
hash['D'] = ;
hash['R'] = ;
scanf("%d",&cas);
while(cas -- )
{
scanf("%d%d",&m,&n);
ac.init();
for(int k = ; k < ; k ++ )
{
scanf("%s",str);
len = strlen(str);
for(int i = ; i < len ; i ++ )
te[i] = hash[str[i]];
ac.add(len,te,<<k);
} ac.build();
int ans ;
ans = ac.solve();
printf("%d\n",ans);
}
return ;
}

hdu4758 Walk Through Squares 自动机+DP的更多相关文章

  1. HDU4758 Walk Through Squares(AC自动机+状压DP)

    题目大概说有个n×m的格子,有两种走法,每种走法都是一个包含D或R的序列,D表示向下走R表示向右走.问从左上角走到右下角的走法有多少种走法包含那两种走法. D要走n次,R要走m次,容易想到用AC自动机 ...

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

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

  3. hdu4758 Walk Through Squares

    地址:http://acm.split.hdu.edu.cn/showproblem.php?pid=4758 题目: Walk Through Squares Time Limit: 4000/20 ...

  4. HDU4758 Walk Through Squares AC自动机&&dp

    这道题当时做的时候觉得是数论题,包含两个01串什么的,但是算重复的时候又很蛋疼,赛后听说是字符串,然后就觉得很有可能.昨天队友问到这一题,在学了AC自动机之后就觉得简单了许多.那个时候不懂AC自动机, ...

  5. HDU3341 Lost's revenge(AC自动机&&dp)

    一看到ACGT就会想起AC自动机上的dp,这种奇怪的联想可能是源于某道叫DNA什么的题的. 题意,给你很多个长度不大于10的小串,小串最多有50个,然后有一个长度<40的串,然后让你将这个这个长 ...

  6. 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 ...

  7. POJ1625 Censored!(AC自动机+DP)

    题目问长度m不包含一些不文明单词的字符串有多少个. 依然是水水的AC自动机+DP..做完后发现居然和POJ2778是一道题,回过头来看都水水的... dp[i][j]表示长度i(在自动机转移i步)且后 ...

  8. HDU2296 Ring(AC自动机+DP)

    题目是给几个带有价值的单词.而一个字符串的价值是 各单词在它里面出现次数*单词价值 的和,问长度不超过n的最大价值的字符串是什么? 依然是入门的AC自动机+DP题..不一样的是这题要输出具体方案,加个 ...

  9. HDU2457 DNA repair(AC自动机+DP)

    题目一串DNA最少需要修改几个基因使其不包含一些致病DNA片段. 这道题应该是AC自动机+DP的入门题了,有POJ2778基础不难写出来. dp[i][j]表示原DNA前i位(在AC自动机上转移i步) ...

随机推荐

  1. ASP.NET之Cookie(坑爹的Response.Cookies.Remove)

    原文:ASP.NET之Cookie(坑爹的Response.Cookies.Remove) 在web开发中Cookie是必不可少的 .NET自然也有一个强大的Cookie操作类,我们用起来也非常方便, ...

  2. Windows Phone开发(22):启动器与选择器之BingMapsDirectionsTask

    原文:Windows Phone开发(22):启动器与选择器之BingMapsDirectionsTask 从今天开发始,我们又开始新的征程,接下来的课程我们要熟悉一下启动器和选择器,其实二者是一样的 ...

  3. PageRank算法MapReduce实现

    如果你现在需要计算网页的排名只有4一:数据如下面的: baidu 10.00 google,sina,nefu google 10.00 baidu sina 10.00 google nefu 10 ...

  4. NSOperation 的使用(下载相关) 图片和文件都是能够的 断点续传 图片逐渐显示

    // // ImageDownloader.h // NSOperationTest // // Created by ydc on 11-10-29. // Copyright 2011年 __My ...

  5. DeviceIoControl 直接从磁盘扇区读文件

    好久没写博客了,近期看了下DeviceIoControl  关于磁盘的应用,特记一文,以备久后查阅. 首先介绍下,文件在磁盘的存储结构(详细能够到网上查询NTFS文件系统相关的教程后者数据恢复方面教程 ...

  6. Iphone CodeSign error: no provisioning profile at path 错

    今天在退房手续,变化了profile,当再次进行整理编译项目时.就出现了这个问题,在xCode 6 开发环境下出现了, 出现这个错误提示Code Sign error: Provisioning pr ...

  7. Sliverlight实例之 绘制扇形和环形图

    一,1道几何题 已知两点坐标确定一条直线,直线上存在一个未知点,起始点与未知点的距离已知 求:未知点坐标 思路,如下: 求AB长度,可以根据两点距离公式 二,写个C#类 定义一个Point类,代表坐标 ...

  8. [原创] linux deepin 2014.1下编译putty

    在网上找了很久,都没有找到linux下直接可以用的putty程序,最终在putty官网找到了源代码 点击下载 把源代码下载回来. 1.下载源代码 2.安装依赖库 如果系统中没有安装过libgtk2.0 ...

  9. OTG驱动分析(二)

    上回介绍了OTG功能的 OTG部分驱动,本片分析OTG功能的从设备部分驱动.从设备的注冊过程和OTG的一样,首先注冊设备. 流程是: 1.定义platform_device结构. 2.定义platfo ...

  10. HDU 4313 Matrix

    水题:在一个双连通的树上有一些点很有破坏性,我们要把这些带破环性的点隔开,就是破坏一些边使这些点之间不连通,破坏一条边需要一点时间,问最少需要多少时间(同一时间只能破坏一个地方,且忽略位置转移的时间) ...