题意:给你两个串,求用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. 使用multiprocessing模块创建进程

    #_author:来童星#date:2019/12/17from multiprocessing import Processimport timeimport os#两个子进程将会调用的两个方法de ...

  2. NOIp2018集训test-9-5(am)

    Problem A. maze 递归处理,题解写得真简单. 我大概这辈子也写不出来这种东西吧. Problem B. count 容易发现合法的数中一定有且仅有两个数加起来等于10,其他数两两配对加起 ...

  3. Intergalactic Map SPOJ - IM

    传送门 我觉得我写得已经和题解一模一样了,不知道为什么就是过不了..懒得拍了,反正不是很难,不太想浪费时间. 1~2~3的一条路径相当于从2~1的一条路径+2~3的一条路径,点不能重复经过,于是拆点. ...

  4. 笨办法学Python记录--习题18 变量 函数 help的由来;if语句,循环和列表,冒泡排序,判断输入字符串的方法

    20140414 记录 习题17 - 33 函数可以做3件事: 1. 给代码片段命名,,就跟“变量”给字符串和数字命名一样. 2. 可以接受参数,就跟你的脚本接受argv 一样. 3. 通过使用#1 ...

  5. 解决Oracle迁移至GreenPlum(PostgreSql)后不支持rownum的问题

    只需在查询结果中添加一列 row_number() over() as rownum即可 如: select row_number() over() as rownum , * from table1 ...

  6. VS2010-MFC(Ribbon界面开发:为Ribbon Bar添加控件)

    转自:http://www.jizhuomi.com/software/253.html 前面一节为大家简单介绍了如何创建Ribbon样式的应用程序框架,本节教程就来初步讲讲怎样为Ribbon Bar ...

  7. LeetCode 852. Peak Index in a Mountain Array (山脉数组的峰顶索引)

    题目标签:Binary Search 题目给了我们一组 int array,让我们找到数组的 peak. 利用 binary search, 如果数字比它后面那个数字小,说明还在上坡,缩小范围到右半边 ...

  8. Devstack配置负载均衡,负载均衡版本V2

    本文为minxihou的翻译文章,转载请注明出处Bob Hou: http://blog.csdn.net/minxihou JmilkFan:minxihou的技术博文方向是 算法&Open ...

  9. 20140402 cmake编译错误原因 同时装了vs2010和vs2012

    1.cmake编译错误原因 在用cmake编译opencv出现的错误 The CXX compiler identification is MSVC 16.0.30319.1 The C compil ...

  10. [AH2017/HNOI2017]单旋

    题目 \(\rm splay\)水平太差,于是得手玩一下才能发现规律 首先插入一个数,其肯定会成为其前驱的右儿子或者是后继的左儿子,进一步手玩发现前驱的右儿子或者是后继的左儿子一定只有一个是空的,我们 ...