与其说这是一次重温AC自动机+dp,倒不如说这是个坑,而且把队友给深坑了。

这个题目都没A得出来,我只觉得我以前的AC自动机的题目都白刷了——深坑啊。

题目的意思是给你两个串,每个串只含有R或者D,要求有多少种长为(n+m)的串(其中有n个R,m个D)同时含有这两个串作为子串。(我就不说题目描述了)

看完了题目我居然一开始用排列组合去做,搞了近一个小时,深坑队友啊。

其实正解是用AC自动机来dp出解的。

什么意思呢?把两个给定的串放到AC字典树上,并且弄好fail指针,变为tire图,构造好AC自动机,然后就是dp了!

怎么dp呢?

可以这样来做,f[x][y][z][k]表示在第x个点,走了y个R,z个D,含有串的情况为k的种类数。

xyz就不用解释了,一看就懂,k是怎么表示状态数的呢?1表示有1个串,2表示两个串?显然不行,到时候有重复的你怎么判断啊 ?

这里k其实是用二进制来表示的,由于每次只有两个串,所有我们用00表示都不含,01表示含有第一个串,10表示含有第二个串,11表示两串都含有。

这样k就只要4就可以了。;

接下来就是自动机和dp的知识了。

我的这个代码写得很冗,效率灰常地低,希望大家不要见怪,我也是为了保险起见。

一开始我还M了好多发,注意这个题目一般至少要32M的内存才能过,hdu上那些900多k的代码我不知道是怎么来的。所以对我来说这个题目还有一点点卡内存的赶脚。

诶不说了说多了都是泪,上代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#define maxn 201
#define maxm 101
#define M 1000000007
using namespace std; int next[maxn][2],f[maxn][maxm][maxm][4],fail[maxn],N,tag[maxn],t,n,m;
char s0[maxn]; void clear()
{
N=0;
memset(next,0,sizeof next);
memset(f,0,sizeof f);
memset(fail,0,sizeof fail);
memset(tag,0,sizeof tag);
} void insert(char s[],int code)
{
int tep,now=0;
for (int i=0; s[i]; i++)
{
if (s[i]=='R') tep=0; else tep=1;
if (!next[now][tep]) next[now][tep]=++N;
now=next[now][tep];
}
tag[now]=(1<<(code-1));
} void buildAC()
{
queue<int>Q;
int now,k,child;
Q.push(0);
while (!Q.empty())
{
now=Q.front(),Q.pop();
for (int i=0; i<2; i++)
{
child=next[now][i];
if (child)
{
Q.push(child);
if (now==0) fail[child]=0;
else
{
k=fail[now];
while (k && !next[k][i]) k=fail[k];
if (next[k][i]) fail[child]=next[k][i];
else fail[child]=0;
}
tag[child]|=tag[fail[child]];
}
else
{
k=fail[now];
next[now][i]=next[k][i];
}
}
}
} int main()
{
int cur,num,ans;
scanf("%d",&t);
while (t--)
{
clear();
scanf("%d%d",&n,&m);
scanf("%s",s0); insert(s0,1);
scanf("%s",s0); insert(s0,2);
buildAC();
f[0][0][0][0]=1;//第0个点,走0步R,走0步D,取得的状态为00
for (int i=0; i<n+m; i++)//总步数
{
for (int k1=0; k1<=min(n,i); k1++)//k1步R
{
int k2=i-k1;
for (int p=0; p<=N; p++)
{
for (int k=0; k<=3; k++)
{
if (f[p][k1][k2][k])
{
if (k1<n)
{
cur=next[p][0];
num=tag[cur]|k;
f[cur][k1+1][k2][num]+=f[p][k1][k2][k];
f[cur][k1+1][k2][num]%=M;
}
if (k2<m)
{
cur=next[p][1];
num=tag[cur]|k;
f[cur][k1][k2+1][num]+=f[p][k1][k2][k];
f[cur][k1][k2+1][num]%=M;
}
}
}
}
}
}
ans=0;
for (int i=0; i<=N; i++) ans=(ans+f[i][n][m][3])%M;
printf("%d\n",ans);
}
return 0;
}

HDU 4758——Walk Through Squares——2013 ACM/ICPC Asia Regional Nanjing Online的更多相关文章

  1. hdu 4751 Divide Groups bfs (2013 ACM/ICPC Asia Regional Nanjing Online 1004)

    SDUST的训练赛 当时死磕这个水题3个小时,也无心去搞其他的 按照题意,转换成无向图,预处理去掉单向的边,然后判断剩下的图能否构成两个无向完全图(ps一个完全图也行或是一个完全图+一个孤点) 代码是 ...

  2. HDU 4749 Parade Show 2013 ACM/ICPC Asia Regional Nanjing Online

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4749 题目大意:给一个原序列N,再给出一个序列M,问从N中一共可以找出多少个长度为m的序列,序列中的数 ...

  3. [2013 ACM/ICPC Asia Regional Nanjing Online C][hdu 4750]Count The Pairs(kruskal + 二分)

    http://acm.hdu.edu.cn/showproblem.php?pid=4750 题意: 定义f(u,v)为u到v每条路径上的最大边的最小值..现在有一些询问..问f(u,v)>=t ...

  4. HDU 4751 Divide Groups 2013 ACM/ICPC Asia Regional Nanjing Online

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4751 题目大意:判断一堆人能否分成两组,组内人都互相认识. 解题思路:如果两个人不是相互认识,该两人之 ...

  5. HDU 4757 Tree(可持久化字典树)(2013 ACM/ICPC Asia Regional Nanjing Online)

    Problem Description   Zero and One are good friends who always have fun with each other. This time, ...

  6. HDU4753 Fishhead’s Little Game——2013 ACM/ICPC Asia Regional Nanjing Online

    今天比赛又是做得好水的.被狂虐啊. 比赛两个多小时一直没出题,遒遒最先交的若干发都wa了.T_T 我独自在一遍苦思了1006这个题,还好最后把这个题目A掉了,不然又是深坑队友. 题目的意思我就不多说了 ...

  7. hduoj 4710 Balls Rearrangement 2013 ACM/ICPC Asia Regional Online —— Warmup

    http://acm.hdu.edu.cn/showproblem.php?pid=4710 Balls Rearrangement Time Limit: 6000/3000 MS (Java/Ot ...

  8. hduoj 4708 Rotation Lock Puzzle 2013 ACM/ICPC Asia Regional Online —— Warmup

    http://acm.hdu.edu.cn/showproblem.php?pid=4708 Rotation Lock Puzzle Time Limit: 2000/1000 MS (Java/O ...

  9. hduoj 4715 Difference Between Primes 2013 ACM/ICPC Asia Regional Online —— Warmup

    http://acm.hdu.edu.cn/showproblem.php?pid=4715 Difference Between Primes Time Limit: 2000/1000 MS (J ...

随机推荐

  1. 20155305 2016-2017-2 《Java程序设计》实验一 Java开发环境的熟悉(macOS + IDEA)

    20155305 2016-2017-2 <Java程序设计>实验一 Java开发环境的熟悉(macOS + IDEA) 实验内容 1.使用JDK编译.运行简单的Java程序: 2.使用E ...

  2. BZOJ054_移动玩具_KEY

    题目传送门 这道题我写IDA*写挂了,TLE+WA,只AC了两个点. 这道题标算BFS+状态压缩. code: /******************************************* ...

  3. Nginx入门篇(二)之Nginx部署与配置文件解析

    一.Nginx编译安装 ()查看系统环境 [root@localhost tools]# cat /etc/redhat-release CentOS Linux release (Core) [ro ...

  4. Linux系统运维基础管理命令总结

    1.查看系统负载命令:w.uptime [root@localhost ~]# w :: up days, :, user, load average: 0.00, 0.01, 0.05 USER T ...

  5. VS2010 不显示 最近使用的项目 解决办法

    昨天重装了VS2010,然后开了项目看了下今天早上再打开发现起始页近使用项目列表是空白的,每次打开项目都要去到指定目录去找解决方案才能打开,感觉很麻烦,在网上找了下解决方案,解决步骤下:菜单 —— 运 ...

  6. Scratch3.0设计的插件系统(上篇)

    我们每个人在内心深处都怀有一个梦想: 希望创造出一个鲜活的世界,一个宇宙.处在我们生活的中间.被训练为架构师的那些人,拥有这样的渴望: 在某一天,在某一个地方,因为某种原因,创造出了一个不可思议的.美 ...

  7. abp 指定方法不生成api

    方法上面添加RemoteServiceAttribute特性

  8. Mac下重置MySQL密码

    第一步要先停止掉mysql服务: brew services stop mysql 第二步查看mysql安装路径: brew info mysql //我这里是brew管理的所以我用brew查看mys ...

  9. 微信小程序模板消息群发解决思路

    基于微信的通知渠道,微信为开发者提供了可以高效触达用户的模板消息能力,以便实现服务的闭环并提供更佳的体验.(微信6.5.2及以上版本支持模板功能.低于该版本将无法收到模板消息.) 模板推送位置:服务通 ...

  10. 区块链技术:每位CEO都应了解

    区块链技术有可能成为一项广泛应用的突破性技术,像蒸汽机.电力或因特网那 样,改变整个社会和经济的运行方式. 对企业而言,信任至关重要.今天,我们基于信任,将钱存放在银行,通过电商企业 网购产品,并且依 ...