1030: [JSOI2007]文本生成器

Time Limit: 1 Sec  Memory Limit: 162 MB

Submit: 2635  Solved: 1090

[

id=1030" style="color:blue; text-decoration:none">Submit][Status][Discuss]

Description

JSOI交给队员ZYX一个任务。编制一个称之为“文本生成器”的电脑软件:该软件的使用者是一些低幼人群,他们如今使用的是GW文本生成器v6版。该软件能够随机生成一些文章―――总是生成一篇长度固定且全然随机的文章—— 也就是说,生成的文章中每一个字节都是全然随机的。假设一篇文章中至少包括使用者们了解的一个单词,那么我们说这篇文章是可读的(我们称文章a包括单词b,当且仅当单词b是文章a的子串)。可是,即使依照这种标准,使用者如今使用的GW文本生成器v6版所生成的文章也是差点儿全然不可读的。
ZYX须要指出GW文本生成器 v6生成的全部文本中可读文本的数量,以便可以成功获得v7更新版。你能帮助他吗?

Input

输入文件的第一行包括两个正整数。各自是使用者了解的单词总数N (<= 60)。GW文本生成器 v6生成的文本固定长度M;下面N行,每一行包括一个使用者了解的单词。

这里全部单词及文本的长度不会超过100,而且仅仅可能包括英文大写字母A..Z  。

Output

一个整数,表示可能的文章总数。仅仅须要知道结果模10007的值。

Sample Input

2 2

A

B

Sample Output

100

ac自己主动机上的dp

dp[0][i][j]表示到第i位,以第j个状态结束不符合条件的串的个数

dp[1][i][j]表示到第i位,以第j个状态结束符合条件的串的个数

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std; const int N = 6005;
const int MOD = 10007; int que[N], fr, ta; struct ACM {
int cnt;
int nxt[N][26], sum[N], fail[N];
void init() {
for(int i = 1; i <= cnt; ++i) {
sum[i] = fail[i] = 0;
for(int j = 0; j < 26; ++j)
nxt[i][j] = 0;
}
cnt = 1;
for(int i = 0; i < 26; ++i) nxt[0][i] = 1;
}
void insert(string str) {
int now = 1;
int len = str.length();
for(int i = 0; i < len; ++i) {
if(nxt[now][str[i] - 'A'] == 0) nxt[now][str[i] - 'A'] = ++cnt;
now = nxt[now][str[i] - 'A'];
}
sum[now] = 1;
}
void build_fail() {
fr = ta = 0;
que[ta++] = 1;
fail[1] = 0;
while(fr != ta) {
int now = que[fr++];
for(int i = 0; i < 26; ++i) {
int x = nxt[now][i];
if(x == 0) continue;
int tmp = fail[now];
while(nxt[tmp][i] == 0) tmp = fail[tmp];
fail[x] = nxt[tmp][i];
que[ta++] = x;
}
}
}
void debug() {
for(int i = 1; i <= cnt; ++i) {
cout<<i<<": "<<"fail = "<<fail[i]<<" [ ";
for(int j = 0; j < 26; ++j) {
if(nxt[i][j]) cout<<char(j + 'A')<<','<<nxt[i][j]<<' ';
}
puts("]");
}
}
void gao(int, int);
} acm; int dp[2][105][N]; void ACM::gao(int n, int m) {
build_fail();
//debug();
memset(dp, 0, sizeof(dp));
dp[0][0][1] = 1;
for(int i = 1; i <= m; ++i) {
for(int j = 1; j <= cnt; ++j) {
int u = j;
for(int k = 0; k < 26; ++k) {
int v = u;
while(nxt[v][k] == 0) v = fail[v];
v = nxt[v][k];
if(sum[v]) {
dp[1][i][v] = (dp[1][i][v] + dp[1][i - 1][u] + dp[0][i - 1][u]) % MOD;
dp[0][i][v] += 0;
} else {
dp[1][i][v] = (dp[1][i][v] + dp[1][i - 1][u]) % MOD;
dp[0][i][v] = (dp[0][i][v] + dp[0][i - 1][u]) % MOD;
}
}
}
}
int ans = 0;
for(int i = 1; i <= cnt; ++i)
ans = (ans + dp[1][m][i]) % MOD;
cout<<ans<<endl;
} string str[65]; bool ok(int x, int n) {
int len = str[x].length();
for(int i = 0; i < n; ++i) {
if(i == x) continue;
int pos = str[x].find(str[i]);
if(pos >= 0 && pos < len) return false;
}
return true;
} int main() {
int n, m;
cin>>n>>m;
acm.init();
for(int i = 0; i < n; ++i) {
cin>>str[i];
}
sort(str, str + n);
n = unique(str, str + n) - str;
for(int i = 0; i < n; ++i) {
if(ok(i, n)) acm.insert(str[i]);
}
acm.gao(n, m);
return 0;
}

bzoj 1030: [JSOI2007]文本生成器 (ac自己主动机上的dp)的更多相关文章

  1. BZOJ 1030: [JSOI2007]文本生成器 [AC自动机 DP]

    1030: [JSOI2007]文本生成器 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 3953  Solved: 1614[Submit][Stat ...

  2. BZOJ 1030 [JSOI2007]文本生成器

    1030: [JSOI2007]文本生成器 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 2624  Solved: 1087[Submit][Stat ...

  3. 【刷题】BZOJ 1030 [JSOI2007]文本生成器

    Description JSOI交给队员ZYX一个任务,编制一个称之为"文本生成器"的电脑软件:该软件的使用者是一些低幼人群,他们现在使用的是GW文本生成器v6版.该软件可以随机生 ...

  4. bzoj 1030 [JSOI2007]文本生成器(AC自动机+DP)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1030 [题意] 给n个小串,随机构造一个长为m的大串,一个串合法当且仅当包含一个或多个 ...

  5. BZOJ 1030 [JSOI2007]文本生成器(AC自动机)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1030 [题目大意] 求出包含任意一个给定串的串数量 [题解] 我们求出不包含任意一个给 ...

  6. 1030: [JSOI2007]文本生成器 ac自动机+dp

    https://www.lydsy.com/JudgeOnline/problem.php?id=1030 求长度为m不包含n个子串的种数, 跑完ac自动机之后没办法跑矩阵快速幂,因为状态数比较大(6 ...

  7. BZOJ 1030 [JSOI2007]文本生成器 (Trie图+DP)

    题目大意:给你一堆字符串,一个串不合法的条件是这些字符串中任意一个是这个串的子串,求合法的串的数量 其实这道题比 [HNOI2008]GT考试 那道题好写一些,但道理是一样的 只不过这道题的答案可以转 ...

  8. 1030: [JSOI2007]文本生成器

    1030: [JSOI2007]文本生成器 https://www.lydsy.com/JudgeOnline/problem.php?id=1030 分析: AC自动机+dp. 正难则反,求满足的, ...

  9. 【BZOJ1030】[JSOI2007]文本生成器 AC自动机+动态规划

    [BZOJ1030][JSOI2007]文本生成器 Description JSOI交给队员ZYX一个任务,编制一个称之为“文本生成器”的电脑软件:该软件的使用者是一些低幼人群,他们现在使用的是GW文 ...

随机推荐

  1. Java总结输入流输出流

    学习Java的同学注意了!!!  学习过程中遇到什么问题或者想获取学习资源的话,欢迎加入Java学习交流群:618528494  我们一起学Java! 1.什么是IO Java中I/O操作主要是指使用 ...

  2. BRVAH(让RecyclerView变得更高效) (2)

    本文来自网易云社区 作者:吴思博 1.2 宫格和列表的混排样式 关于 Grid 和List 的混排样式,Grid 样式是一行有多个,而 List样式是一行只有一个. 我们可以把 List 样式看成是G ...

  3. Cocoa-Cocoa框架

    1.Cocoa是什么? Cocoa是OS X和 iOS操作系统的程序的运行环境. 是什么因素使一个程序成为Cocoa程序呢?不是编程语言,因为在Cocoa开发中你可以使用各种语言:也不是开发工具,你可 ...

  4. Scrapy应用之抓取《宦海沉浮》小说

    目标站点   http://www.shushu8.com/huanhaichenfu/ 第一步:新建项目 KeysdeMacBook:Desktop keys$ scrapy startprojec ...

  5. HDU 3341 Lost's revenge

    Lost's revenge Time Limit: 5000ms Memory Limit: 65535KB This problem will be judged on HDU. Original ...

  6. 九度oj 题目1035:找出直系亲属

    题目描述:     如果A,B是C的父母亲,则A,B是C的parent,C是A,B的child,如果A,B是C的(外)祖父,祖母,则A,B是C的grandparent,C是A,B的grandchild ...

  7. 快速排序php

    <?php /** * Created by PhpStorm. * User: brady.wang * Date: 2017/11/10 * Time: 9:45 */ $arr=array ...

  8. cell左右滑动展开更多按钮-MGSwipeTableCell

    MGSwipeTableCell是一个UITableViewCell的子类, 它实现了左,右滑动展开更多按钮用来实现一些相关操作就和QQ好友列表滑动展开的按钮一样,封装的很好,动画效果也处理很到位,废 ...

  9. 如何解决 错误code signing is required for product type 'xxxxx' in SDK 'iOS 8.2'

    如何解决 错误code signing is required for product type 'xxxxx' in SDK 'iOS 8.2' 大家在做真机调试的时候,或许会遇到这样的问题,那如何 ...

  10. POJ 3693 Maximum repetition substring ——后缀数组

    重复次数最多的字串,我们可以枚举循环节的长度. 然后正反两次LCP,然后发现如果长度%L有剩余的情况时,答案是在一个区间内的. 所以需要找到区间内最小的rk值. 两个后缀数组,四个ST表,$\Thet ...