题意:给你两个串,求用m个R,n个D能组成多少个包含这两个串

题解:先构造一个AC自动机记录每个状态包含两个串的状态,

状态很容易定义 dp【i】【j】【k】【status】表示在AC自动机K这个节点

使用了 i 个D,j个R ,状态为status的方案数。

然后直接DP即可。

 #include <set>
#include <map>
#include <stack>
#include <queue>
#include <cmath>
#include <ctime>
#include <cstdio>
#include <string>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <unordered_map> #define pi acos(-1.0)
#define eps 1e-9
#define fi first
#define se second
#define rtl rt<<1
#define rtr rt<<1|1
#define bug printf("******\n")
#define mem(a, b) memset(a,b,sizeof(a))
#define name2str(x) #x
#define fuck(x) cout<<#x" = "<<x<<endl
#define sfi(a) scanf("%d", &a)
#define sffi(a, b) scanf("%d %d", &a, &b)
#define sfffi(a, b, c) scanf("%d %d %d", &a, &b, &c)
#define sffffi(a, b, c, d) scanf("%d %d %d %d", &a, &b, &c, &d)
#define sfL(a) scanf("%lld", &a)
#define sffL(a, b) scanf("%lld %lld", &a, &b)
#define sfffL(a, b, c) scanf("%lld %lld %lld", &a, &b, &c)
#define sffffL(a, b, c, d) scanf("%lld %lld %lld %lld", &a, &b, &c, &d)
#define sfs(a) scanf("%s", a)
#define sffs(a, b) scanf("%s %s", a, b)
#define sfffs(a, b, c) scanf("%s %s %s", a, b, c)
#define sffffs(a, b, c, d) scanf("%s %s %s %s", a, b,c, d)
#define FIN freopen("../in.txt","r",stdin)
#define gcd(a, b) __gcd(a,b)
#define lowbit(x) x&-x
#define IO iOS::sync_with_stdio(false) using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
const ULL seed = ;
const LL INFLL = 0x3f3f3f3f3f3f3f3fLL;
const int maxn = 1e6 + ;
const int maxm = 8e6 + ;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + ;
int T, m, n;
char buf[];
int dp[][][][]; int get_num(char ch) {
if (ch == 'D') return ;
else return ;
} struct Aho_Corasick {
int next[][], fail[], End[];
int root, cnt; int newnode() {
for (int i = ; i < ; i++) next[cnt][i] = -;
End[cnt++] = ;
return cnt - ;
} void init() {
cnt = ;
root = newnode();
} void insert(char buf[], int id) {
int len = strlen(buf);
int now = root;
for (int i = ; i < len; i++) {
if (next[now][get_num(buf[i])] == -) next[now][get_num(buf[i])] = newnode();
now = next[now][get_num(buf[i])];
}
End[now] |= ( << id);
} 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]);
}
}
} LL solve() {
mem(dp, );
dp[][][][] = ;
for (int i = ; i <= n; ++i) {
for (int j = ; j <= m; ++j) {
for (int k = ; k < cnt; ++k) {
for (int status = ; status < ; ++status) {
if (dp[i][j][k][status] == ) continue;
for (int l = ; l < ; ++l) {
int idx = next[k][l];
if (l == ) {
dp[i + ][j][idx][status | End[idx]] =
(1LL * dp[i + ][j][idx][status | (End[idx])] + 1LL * dp[i][j][k][status]) %
mod;
// printf("i = %d j = %d idx = %d status = %d dp = %lld\n", i + 1, j, idx,
// status | (End[idx]),
// dp[i + 1][j][idx][status | End[idx]]);
} else {
dp[i][j + ][idx][status | End[idx]] =
(1LL * dp[i][j + ][idx][status | End[idx]] + 1LL * dp[i][j][k][status]) % mod;
// printf("i = %d j = %d idx = %d status = %d dp = %lld\n", i, j + 1, idx,
// status | (End[idx]),
// dp[i][j + 1][idx][status | End[idx]]);
}
}
}
}
}
}
LL ans = ;
for (int i = ; i < cnt; ++i) ans = (ans + dp[n][m][i][]) % mod;
return ans;
} void debug() {
for (int i = ; i < cnt; i++) {
printf("id = %3d,fail = %3d,end = %3d,chi = [", i, fail[i], End[i]);
for (int j = ; j < ; j++) printf("%2d", next[i][j]);
printf("]\n");
}
}
} ac; int main() {
// FIN;
sfi(T);
while (T--) {
sffi(m, n);
ac.init();
for (int i = ; i < ; ++i) {
sfs(buf);
ac.insert(buf, i);
}
ac.build();
printf("%lld\n", ac.solve());
}
return ;
}

Walk Through Squares HDU - 4758 AC自动机+简单状压DP的更多相关文章

  1. HDU3247 Resource Archiver (AC自动机+spfa+状压DP)

    Great! Your new software is almost finished! The only thing left to do is archiving all your n resou ...

  2. HDU - 3247 Resource Archiver (AC自动机,状压dp)

    \(\quad\)Great! Your new software is almost finished! The only thing left to do is archiving all you ...

  3. Resource Archiver HDU - 3247 AC自动机+BFS+状压

    题意: 给出n个资源串,m个病毒串,现在要如何连接资源串使得不含病毒串(可以重叠,样例就是重叠的). 题解: 这题的套路和之前的很不同了,之前的AC自动机+DP的题目一般都是通过teir图去转移, 这 ...

  4. HDU 3247 Resource Archiver (AC自动机+BFS+状压DP)

    题意:给定 n 个文本串,m个病毒串,文本串重叠部分可以合并,但合并后不能含有病毒串,问所有文本串合并后最短多长. 析:先把所有的文本串和病毒都插入到AC自动机上,不过标记不一样,可以给病毒标记-1, ...

  5. 小明系列故事――女友的考验 HDU - 4511 AC自动机+简单DP

    题意:自己看题目,中文体面. 题解: 把所有不能走的路径放入AC自动机中. 然后DP[i][j]表示走到 i 这个点,且位于AC自动机 j 这个节点最短距离 然后直接DP即可.注意一点会爆int #i ...

  6. HDU 6149 Valley Numer II 状压DP

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6149 题意:中文题目 解法:状压DP,dp[i][j]代表前i个低点,当前高点状态为j的方案数,然后枚 ...

  7. HDU 5434 Peace small elephant 状压dp+矩阵快速幂

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5434 Peace small elephant  Accepts: 38  Submissions: ...

  8. HDU 1074 Doing Homework(状压DP)

    第一次写博客ORZ…… http://acm.split.hdu.edu.cn/showproblem.php?pid=1074 http://acm.hdu.edu.cn/showproblem.p ...

  9. HDU 5657 CA Loves Math 状压DP + 枚举

    题意: 给出\(A(2 \leq A \leq 11), n(0 \leq n \leq 10^9), k(1 \leq k \leq 10^9)\). 求区间\([1, A^n]\)中各个数字互不相 ...

随机推荐

  1. NOIp2018集训test-9-21(am/pm)

    Am DAY1 抄代码 送分题 //Achen #include<bits/stdc++.h> #define For(i,a,b) for(int i=(a);i<=(b);i++ ...

  2. 笔试题-求小于等于N的数中有多少组素勾股数

    题目描述: 一组勾股数满足:a2+b2=c2: 素勾股数:a,b,c彼此互质. 输入正整数N: 输出小于等于N的数中有多少组勾股数. 例: 输入:10 输出:1 思路:我是直接暴力破解的…… 首先找出 ...

  3. SecureCRT是最常用的终端仿真程序,简单的说就是Windows下登录UNIX或Liunx服务器主机的软件,本文主要介绍SecureCRT的使用方法和技巧

    SecureCRT是最常用的终端仿真程序,简单的说就是Windows下登录UNIX或Liunx服务器主机的软件,本文主要介绍SecureCRT的使用方法和技巧 VanDyke CRT 和 VanDyk ...

  4. [转]C++ 使用Makefile文件

    //*********list class.h**********class tdate {private:int month;int day;int year;public:tdate();tdat ...

  5. static 关键字的使用及说明

    static 关键字主要有以下几种使用场景: 修饰类的成员变量. 修饰类的成员方法. 修饰类的代码块. 修饰内部类. 1. static 修饰类的成员变量时,被称为静态成员变量.引用 static 修 ...

  6. linux下链接时缺少动态链接库

    1, 用ln将需要的so文件链接到/usr/lib或者/lib这两个默认的目录下边 ln -s /where/you/install/lib/*.so /usr/libsudo ldconfig 2, ...

  7. VO和DO的区别

    阿里巴巴Java开发手册中的DO.DTO.BO.AO.VO.POJO定义 分层领域模型规约: DO( Data Object):与数据库表结构一一对应,通过DAO层向上传输数据源对象. DTO( Da ...

  8. Java设计模式(一)外观模式(门面模式)- 结构型模式

    模式的定义 门面模式(Facade Pattern)也叫做外观模式,是一种比较常用的封装模式,其定义如下:要求一个子系统的外部与其内部通信必须通过一个统一的对象进行.门面模式提供一个高层次的接口,使得 ...

  9. iOS开发系列-Category

    Category Category是OC中特有的语法.Category的作用 * 可以在不修改原来类的基础上,为这个类扩充一些方法 * 一个庞大的类可以分为多个模块开发 * 一个庞大的类可以由多个人来 ...

  10. Spark三种部署方式