题意:给你两个串A,B, 问一个串长为M+N且包含A和B且恰好包含M个R的字符串有多少种组合方式,所有字符串中均只含有字符L和R。

dp[i][j][k][S]表示串长为i,有j个R,在自动机中的状态为k,包含AB的状态为S的方案个数。

PS1.之前用long long int超时了两次

PS2.把行列搞错了WA了几次

#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring> //#define LL long long int using namespace std; const int MAX_NODE = ;
const int CHILD_NUM = ;
const int MAXN = ;
const int MOD = ; struct ACAutomaton
{
int chd[MAX_NODE][CHILD_NUM]; //每个节点的儿子,即当前节点的状态转移
int val[MAX_NODE]; //记录题目给的关键数据
int fail[MAX_NODE]; //传说中的fail指针
int Q[MAX_NODE<<]; //队列,用于广度优先计算fail指针
int ID[]; //字母对应的ID
int sz; //已使用节点个数 //初始化,计算字母对应的儿子ID,如:'a'->0 ... 'z'->25
void Initialize()
{
fail[] = ;
ID['L'] = ;
ID['R'] = ;
return;
}
//重新建树需先Reset
void Reset()
{
memset(chd[] , , sizeof(chd[]));
val[] = ;
sz = ;
}
//将权值为key的字符串a插入到trie中
void Insert(char *a,int key)
{
int p = ;
for ( ; *a ; a ++)
{
int c = ID[*a];
if (!chd[p][c])
{
memset(chd[sz] , , sizeof(chd[sz]));
val[sz] = ;
chd[p][c] = sz ++;
}
p = chd[p][c];
}
val[p] = key;
}
//建立AC自动机,确定每个节点的权值以及状态转移
void Construct()
{
int *s = Q , *e = Q;
for (int i = ; i < CHILD_NUM ; i ++)
{
if (chd[][i])
{
fail[ chd[][i] ] = ;
*e ++ = chd[][i];
}
}
while (s != e)
{
int u = *s++;
for (int i = ; i < CHILD_NUM ; i ++)
{
int &v = chd[u][i];
if (v)
{
*e ++ = v;
fail[v] = chd[ fail[u] ][i];
//以下一行代码要根据题目所给val的含义来写
val[v] |= val[ fail[v] ];
}
else
{
v = chd[ fail[u] ][i];
}
}
}
}
} AC; int M, N;
char str[MAXN];
int dp[][MAXN][MAXN<<][<<]; void solved()
{
int pre = , cur = ; memset( dp[], , sizeof(dp[]) );
dp[][][][] = ;
int all = << ;
int L = M + N; for ( int i = ; i < L; ++i )
{
memset( dp[cur], , sizeof(dp[cur]) );
for ( int j = ; j <= M; ++j )
for ( int k = ; k < AC.sz; ++k )
for ( int r = ; r < ; ++r )
for ( int S = ; S < all; ++S )
{
int next = AC.chd[k][r];
dp[cur][j+r][next][ S|AC.val[next] ] += dp[pre][j][k][S];
dp[cur][j+r][next][ S|AC.val[next] ] %= MOD;
} cur ^= ;
pre ^= ;
} int ans = ;
for ( int j = ; j < AC.sz; ++j )
{
ans += dp[pre][M][j][all-];
ans %= MOD;
}
printf( "%d\n", ans ); return;
} int main()
{
AC.Initialize();
int T;
scanf( "%d", &T );
while ( T-- )
{
scanf( "%d%d", &M, &N );
AC.Reset();
for ( int i = ; i < ; ++i )
{
scanf( "%s", str );
AC.Insert( str, << i );
}
AC.Construct(); solved();
}
return ;
}

HDU 4758 Walk Through Squares( AC自动机 + 状态压缩DP )的更多相关文章

  1. HDU 4758 Walk Through Squares(AC自动机+DP)

    题目链接 难得出一个AC自动机,我还没做到这个题呢...这题思路不难想,小小的状压出一维来,不过,D和R,让我wa死了,AC自动机,还得刷啊... #include<iostream> # ...

  2. HDU 4057 Rescue the Rabbit ( AC自动机 + 状态压缩DP )

    模板来自notonlysuccess. 模式串只有10个,并且重复出现的分值不累加,因此很容易想到状态压缩. 将模式串加入AC自动机,最多有10*100个状态. dp[i][j][k]:串长为i,在T ...

  3. HDU - 4758 Walk Through Squares (AC自己主动机+DP)

    Description   On the beaming day of 60th anniversary of NJUST, as a military college which was Secon ...

  4. HDU 4511 (AC自动机+状态压缩DP)

    题目链接:  http://acm.hdu.edu.cn/showproblem.php?pid=4511 题目大意:从1走到N,中间可以选择性经过某些点,比如1->N,或1->2-> ...

  5. hdu 4057(ac自动机+状态压缩dp)

    题意:容易理解... 分析:题目中给的模式串的个数最多为10个,于是想到用状态压缩dp来做,它的状态范围为1-2^9,所以最大为2^10-1,那我们可以用:dp[i][j][k]表示长度为i,在tri ...

  6. POJ 3691 (AC自动机+状态压缩DP)

    题目链接:  http://poj.org/problem?id=3691 题目大意:给定N个致病DNA片段以及一个最终DNA片段.问最终DNA片段最少修改多少个字符,使得不包含任一致病DNA. 解题 ...

  7. bzoj1195 神奇的ac自动机+状态压缩dp

    /* 难的不是ac自动机,是状态压缩dp 之前做了一两题类似题目,感觉理解的还不够透彻 */ #include<iostream> #include<cstdio> #incl ...

  8. HDU 4758 Walk Through Squares ( Trie图 && 状压DP && 数量限制类型 )

    题意 : 给出一个 n 行.m 列的方格图,现从图左上角(0, 0) 到右下角的 (n, m)走出一个字符串(规定只能往下或者往右走),向右走代表' R ' 向下走则是代表 ' D ' 最后从左上角到 ...

  9. hdu 2825(ac自动机+状态压缩dp)

    题意:容易理解... 分析:在做这道题之前我做了hdu 4057,都是同一种类型的题,因为题中给的模式串的个数最多只能为10个,所以我们就很容易想到用状态压缩来做,但是开始的时候我的代码超时了dp时我 ...

随机推荐

  1. 【Java】Maven安装、Eclipse配置以及相关错误解决集合

    作者呕血总结,下面写的每一个错误我都遇过 · Maven安装 · Eclipse配置 · Maven安装 安装前请确保已经装有JDK. 一. 准备Maven程序包 到官网https://maven.a ...

  2. 【课堂笔记精选】为了能够用“Unity”软件做游戏,我要从最基础的开始复习JavaScript

    [声明]在“随笔”模块,只是知识点,但是在“文章”模块(https://www.cnblogs.com/Robot-DX3906/articles/10579584.html)里面,有更多内容. 20 ...

  3. 路由传参,path和query的刷新报错js文件丢失

    日常的路由跳转,基本都会用到传参,有两种方式:path + query, name + params 常用的写法: this.$router.push({ path: 'proDetail',quer ...

  4. Wuss Weapp 一款高质量,组件齐全,高自定义的微信小程序 UI 组件库

    Wuss Weapp 一款高质量,组件齐全,高自定义的微信小程序 UI 组件库 文档 https://phonycode.github.io/wuss-weapp 扫码体验 使用微信扫一扫体验小程序组 ...

  5. Java分享笔记:FileInputStream流的 read()方法 和 read(byte[] b)方法

    /*------------------------ FileInputStream: ....//输入流,字节流 ....//从硬盘中存在的一个文件中读取内容,读取到程序中 ....//read() ...

  6. MappingException:class com.zsn.crm.Model.user not found whie looking for property user id

    之前好好地运行 什么东西都没动过 再次运行突然报异常*****MappingException:class com.zsn.crm.Model.user not found whie looking ...

  7. java 微信开发 常用工具类(xml传输和解析 json转换对象)

    与微信通信常用工具(xml传输和解析) package com.lownsun.wechatOauth.utl; import java.io.IOException; import java.io. ...

  8. linux通用GPIO驱动,写GPIO文件不立即生效问题解决

    Linux开发平台实现了通用GPIO的驱动,用户通过,SHell或者系统调用能控制GPIO的输出和读取其输入值.其属性文件均在/sys/class/gpio/目录下,该目录下有export和unexp ...

  9. POJ 2084 Catalan

    Game of Connections Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 8772   Accepted: 43 ...

  10. python——numpy_1图像基本操作

    1.图像的数组表示: from PIL import Image from pylab import * from numpy import * im = array(Image.open('E:\P ...