题意:给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. Ctrl+Alt+T 文档大纲

  2. 使用JSP实现商场购物车模块

    这些日子,学习JSP,只要找到一个小模块来试试你的手: 这里是实现车模块结果页面截图: 图1. 产品显示页面 通过此页面进行产品选择.增加到购物车 图2 .购物车页面 图3 . 商品数量设置 好了,先 ...

  3. 插入排序java

    插入排序简述 插入排序的基本操作就是将一个数据插入到已经排好序的有序数据中,从而得到一个新的.个数加一的有序数据.   第一个元素是有序队列,从第二个元素开始向有序队列中插入,插入完成后将第三个元素向 ...

  4. 交叉编译libxml2

    请勿用于商业用途,转载请注明出处! xml的优势就是可以方便的管理配置项,libxml2是c语言实现的xml管理库,眼下项目须要ARM下的版本号,libxml2编译过程例如以下: 0.准备工作 下载地 ...

  5. html风格的滚动条

    DIV辊棒的设置 (CSS)2008/09/26 03:07div 控制滚动条2008年01月06日本 星期日 01:181)隐藏滚动条<body style="overflow-x: ...

  6. 这两个成员函数inline重新virtual种类

    inlineType表示在编译时扩展功能,随着在函数调用的函数体而出替换函数调用:和vitual它是c++多态的必要条件,但为了表现出多态性,您将需要等到执行,要知道什么是真正的函数调用.从表面上看这 ...

  7. Lua Development Tools (LDT)

    http://www.eclipse.org/ldt/ Lua Development Tools (LDT) is about providing Lua developers with an ID ...

  8. 采用UltraISO制作U菜Win7安装盘,显现&quot;File not find /BOOT/CDMENU.EZB.ezb&quot;错误

    一机公司Win7动力password不知道.这台机器也很慢, 刷新Win7,运用32位Ghost设备ISO档.从机U之后启动盘,演出 "File not find /BOOT/CDMENU. ...

  9. 【SEO 决胜网络索引】 课程大纲及第一部分第一课:网络营销战略中的索引

    内容简介 1.课程大纲 2.第一部分第一课: 网络营销战略中的索引 3.第一部分第二课预告: 索引是什么 课程大纲 现在是网络为王的时代,人们越来越离不开互联网: SEO(Search Engine ...

  10. Windows 8实例教程系列 - 布局控制

    原文:Windows 8实例教程系列 - 布局控制 与传统应用类似,Windows store应用允许开发人员通过布局控件管理应用UI. 本篇将讨论Windows8布局设计控制. Windows 8布 ...