题目

P4045 [JSOI2009]密码

做法

AC自动机+状压+爆搜

建AC自动机是显然的,顺便预处理\(lst_i\)表示\(i\)结点以哪些串结束(二进制)

然后跑状压\(dp[i][j][k]\)表\(i\)长度现在在\(j\)结点已经出现的串\(k\),理解:自由结点则由根节点\(0\)传递

毒瘤的地方在于输出串,显然\(ans<=42\)时,没有自由结点

两遍爆搜:

\(~~~~~\)第一遍预处理\(visit[i][j][k]\),其中\(i,j,k\)和\(dp\)数组相同,数组内存的值表示是否有效

\(~~~~~\)第二遍直接跑\(visit\),有效才能搜过去

My complete

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<string>
#include<iostream>
#include<cmath>
#include<queue>
using namespace std;
typedef int LL;
const LL maxn=200;
LL L,n,nod,Up;
long long ans;
LL lst[maxn],son[maxn][26],fail[maxn];
long long dp[30][maxn][1<<11];
inline void Insert(char *s,LL id){
LL Len(strlen(s+1)),now(0);
for(LL i=1;i<=Len;++i){
LL c(s[i]-'a');
if(son[now][c]==0) son[now][c]=++nod;
now=son[now][c];
}lst[now]=1<<(id-1);
}
inline void F_trie(){
queue<LL>que;
for(LL i=0;i<26;++i)
if(son[0][i]) que.push(son[0][i]);
while(que.size()){
LL u(que.front()); que.pop();
lst[u]|=lst[fail[u]];
for(LL i=0;i<26;++i){
LL v(son[u][i]);
if(v){
fail[v]=son[fail[u]][i];
que.push(v);
}else son[u][i]=son[fail[u]][i];
}
}
}
LL sta[30],visit[30][maxn][1<<11];
void Dfs(LL len,LL now,LL bit){
if(len==L){
for(LL i=0;i<L;++i)
printf("%c",sta[i]+'a');printf("\n");
return;
}
for(LL i=0;i<26;++i){
LL v(son[now][i]);
if(v==0||visit[len+1][v][bit|lst[v]]!=1) continue;
sta[len]=i;
Dfs(len+1,v,bit|lst[v]);
}
}
bool First(LL len,LL now,LL bit){
if(visit[len][now][bit]==1) return true;
else if(visit[len][now][bit]==-1) return false;
else if(len==L){
visit[len][now][bit]=-1; return false;
}
for(LL i=0;i<26;++i){
LL v(son[now][i]);
if(v==0) continue;
if(First(len+1,v,bit|lst[v]))
visit[len][now][bit]=1;
}
if(visit[len][now][bit]!=1){
visit[len][now][bit]=-1;
return false;
}return true;
}
inline void Solve(){
for(LL i=0;i<L;++i)
for(LL u=0;u<=nod;++u)
for(LL pre=0;pre<Up;++pre)
if(dp[i][u][pre]) First(i,u,pre);
Dfs(0,0,0);
}
char s[maxn];
int main(){
scanf("%d %d",&L,&n);
for(LL i=1;i<=n;++i){
scanf(" %s",s+1),
Insert(s,i);
}F_trie();
Up=(1<<n);
dp[0][0][0]=1;
for(LL i=1;i<=L;++i)
for(LL u=0;u<=nod;++u)
for(LL pre=0;pre<Up;++pre){
if(dp[i-1][u][pre]==0) continue;
for(LL k=0;k<26;++k){
LL v(son[u][k]);
dp[i][v][pre|lst[v]]+=dp[i-1][u][pre];
}
}
for(LL i=0;i<=nod;++i){
if(dp[L][i][Up-1])
visit[L][i][Up-1]=1,
ans+=dp[L][i][Up-1];
else visit[L][i][Up-1]=-1;
}
printf("%lld\n",ans);
if(ans<=42)
Solve();
return 0;
}/*
*/

P4045 [JSOI2009]密码的更多相关文章

  1. 洛谷$P4045\ [JSOI2009]$密码 $dp$+$AC$自动机

    正解:$dp$+$AC$自动机+搜索 解题报告: 传送门$QwQ$ 首先显然先建个$AC$自动机,然后考虑设$f_{i,j,k}$表示长度为$i$,现在在$AC$自动机的第$j$个位置,已经表示出来的 ...

  2. BZOJ 1559: [JSOI2009]密码( AC自动机 + 状压dp )

    建AC自动机后, dp(x, y, s)表示当前长度为x, 在结点y, 包括的串的状态为s的方案数, 转移就在自动机上走就行了. 对于输出方案, 必定是由给出的串组成(因为<=42), 所以直接 ...

  3. bzoj1559 [JSOI2009]密码

    题目链接:[JSOI2009]密码 我们先看第一问:输出方案数 我们把所有给出来的串丢到AC自动机里面去,然后在建出来的\(trie\)图上跑dp 由于\(n\leq 10\)我们很自然的就想到了状压 ...

  4. 【BZOJ1559】[JSOI2009]密码(AC自动机,动态规划,搜索)

    [BZOJ1559][JSOI2009]密码(AC自动机,动态规划,搜索) 题面 BZOJ 洛谷 题解 首先求方案数显然是构建\(AC\)自动机之后再状压\(dp\),似乎没有什么好讲的. 现在考虑答 ...

  5. [JSOI2009]密码 [AC自动机]

    题面 bzoj luogu 首先看到这题就知道随便暴枚 只要是多项式算法都能过 先常规建AC自动机 注意被别的单词包含的单词没有存在的价值 剩余单词状压 大力dp f[长度][节点编号][状态] \( ...

  6. BZOJ1559[JSOI2009]密码——AC自动机+DP+搜索

    题目描述 输入 输出 样例输入 10 2 hello world 样例输出 2 helloworld worldhello 提示 这题算是一个套路题了,多个串求都包含它们的长为L的串的方案数. 显然是 ...

  7. JSOI2009 密码 和 JSOI2007 文本生成器 和 ZOJ3545 Rescue the Rabbit

    密码 众所周知,密码在信息领域起到了不可估量的作用.对于普通的登陆口令,唯一的破解 方法就是暴力破解一逐个尝试所有可能的字母组合,但这是一项很耗时又容易被发现的工 作.所以,为了获取对方的登陆口令,在 ...

  8. [BZOJ 1559] [JSOI2009] 密码 【AC自动机DP】

    题目链接:BZOJ - 1559 题目分析 将给定的串建成AC自动机,然后在AC自动机上状压DP. 转移边就是Father -> Son 或 Now -> Fail. f[i][j][k] ...

  9. BZOJ 1559 JSOI2009 密码 状压dp+AC自动机+搜索

    题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1559 分析: 这个题意真的是很**啊!!!直接说每一个字符串至少出现一次不就好了吗... ...

随机推荐

  1. 使用PostMan快速生成代码

    Postman是一款功能强大的网页调试与发送网页HTTP请求的Chrome插件.关于PostMan的下载和使用网上有很多相关的博客介绍,本文主要介绍PostMan在进行模拟Http请求后可以根据需要的 ...

  2. centos安装pcntl扩展

    php为源码安装,安装目录为/www/php/,源码包目录为/www/software/php-5.6.30 首先,进入到源码包中扩展目录 /www/software/php-5.6.30/ext/p ...

  3. HTML css样式

    clear: both清除左侧和右侧浮动 status: 变量状态参数,该属性有5个常用值count 表示当前遍历集合的元素个数index 表示当前遍历到集合的第几个元素current 表示当前的集合 ...

  4. Django--基础补充

    render 函数 在Django的使用中,render函数大多与浏览器发来的GET请求一并出现,它的使用方法非常简单 例如:render(request,"xxx.html",{ ...

  5. Unity3d 发动机原理详细介绍

    Unity3d 发动机原理详细介绍 www.MyException.Cn   发布于:2013-10-08 16:32:36   浏览:46次 0     Unity3d 引擎原理详细介绍 体系结构 ...

  6. scala 编写wordCount

    加载文件 scala> var f1=sc.textFile("/tmp/dataTest/followers.txt") scala> f1.flatMap(x=&g ...

  7. NPOI 计算单元格高度

    需求 要导出一个Excel,第一行是不定长字符串,合并单元格(A-G)已知,现要计算第一行的高度. 思路 已知,NPOI的宽度单位是1/256个英文字符,在本例中,A列的宽度是2048,即 2048 ...

  8. JavaWeb学习总结第六篇--认识Session机制

    认识Session机制 前文也提到过,常用的会话跟踪有两种技术:Cookie和Session.今天就为大家讲解一下Session机制. 什么是Session? Session是另一种记录客户状态的机制 ...

  9. 8168开发之---1g内存换成512M的内存映射配置

    最近在帮新来同事调式内存分配,起初是将config.bld 中的内存在标配的基础上减少sr1,和tiler 将dsp从9m增加到16m,然后编译通过, 可是在加载的时候卡住了,init.sh 过,lo ...

  10. android 二维码制作,显示到UI,并保存SD卡,拿来就能用!!

    转载请注明出处:王亟亟的大牛之路 如今二维码已经渗透了我们的生活.各种扫码关注啊.扫码下载的,今天上一个依据输入内容生成二维码的功能. 包结构: 界面截图: 功能:输入网址–>生成图片–> ...