题目链接:HDU-2825

题意:给出m个单词,要构造出满足包含其中大于等于k个单词的字符串,字符只包括小写字母,问长度为n的这样的串有多少个。

思路:令dp[i][j][k]表示当前已经构造了i个字符,在ac自动机上跑到结点j,且单词状态为k情况下的方案数。从dp[i][j][k]向dp[i+1]递推。注意单词可能重复出现。

代码:

 #include<cstdio>
#include<cstdlib>
#include<vector>
#include<set>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<iostream>
#include<queue>
using namespace std;
typedef long long LL;
const LL MAXN=2e3+;
const LL INF=0x3f3f3f3f;
const LL MOD=; struct AC
{
int ch[MAXN][];
vector<int> val[MAXN];
int sz;
AC() { init(); }
void init() { sz=; memset(ch[],,sizeof(ch[])); val[].clear();}
int idx(char c)
{
return c-'a';
}
void insert(char *s,int v)
{
int u=,n=strlen(s);
for(int i=;i<n;i++)
{
int c=idx(s[i]);
if(!ch[u][c])
{
memset(ch[sz],,sizeof(ch[sz]));
val[sz].clear();
ch[u][c]=sz++;
}
u=ch[u][c];
}
val[u].push_back(v);
}
int f[MAXN];
int last[MAXN];
void getFail()
{
queue<int> q;
f[]=;
for(int c=;c<;c++)
{
int u=ch[][c];
if(u) {f[u]=;q.push(u);last[u]=;}
}
while(!q.empty())
{
int r=q.front();q.pop();
for(int c=;c<;c++)
{
int u=ch[r][c];
if(!u)
{
ch[r][c]=ch[f[r]][c];
continue;
}
q.push(u);
int v=f[r];
while(v && !ch[v][c]) v=f[v];
f[u]=ch[v][c];
last[u]=(val[f[u]].size())?f[u]:last[f[u]];
}
}
}
};
AC T;
int f[][][];
bool isOK(int x,int k)
{
int sum=;
for(int i=;i<=;i++)
if(x&(<<i))
sum++;
return sum>=k;
}
int main()
{
#ifdef LOCAL
freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
#endif
int n,m,K;
while(scanf("%d%d%d",&n,&m,&K)!=EOF && (n || m || K))
{
T.init();
for(int i=;i<=m;i++)
{
char s[];
scanf("%s",s);
T.insert(s,i);
}
T.getFail();
memset(f,,sizeof(f));
f[][][]=;
for(int i=;i<n;i++)
{
for(int j=;j<T.sz;j++)
for(int k=;k<(<<(m+));k++)
f[-i%][j][k]=;
for(int j=;j<T.sz;j++)
for(int k=;k<(<<(m+));k++)
if(f[i%][j][k])
for(int jj=;jj<;jj++)
{
int v= T.ch[j][jj];
int kk=k;
if(T.val[v].size())
{
for(unsigned int ii=;ii<T.val[v].size();ii++)
{
if((kk&(<<T.val[v][ii]))==)
kk+=(<<T.val[v][ii]);
}
}
while(T.last[v]!=)
{
v=T.last[v];
if(T.val[v].size())
{
for(unsigned int ii=;ii<T.val[v].size();ii++)
{
if((kk&(<<T.val[v][ii]))==)
kk+=(<<T.val[v][ii]);
}
}
}
v=T.ch[j][jj];
f[(i+)%][v][kk]=(f[i%][j][k]+f[(i+)%][v][kk])%MOD;
}
}
int ans=;
for(int i=;i<T.sz;i++)
for(int k=;k<(<<(m+));k+=)
if(isOK(k,K))
ans=(ans+f[n%][i][k])%MOD;
printf("%d\n",ans);
}
return ;
}

HDU 2825 Wireless Password的更多相关文章

  1. HDU 2825 Wireless Password (AC自己主动机,DP)

    pid=2825">http://acm.hdu.edu.cn/showproblem.php? pid=2825 Wireless Password Time Limit: 2000 ...

  2. hdu 2825 Wireless Password(ac自己主动机&amp;dp)

    Wireless Password Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others ...

  3. HDU - 2825 Wireless Password(AC自己主动机+DP)

    Description Liyuan lives in a old apartment. One day, he suddenly found that there was a wireless ne ...

  4. HDU - 2825 Wireless Password (AC自动机+状压DP)

    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=2825 题意:给一些字符串,构造出长度为n的字符串,它至少包含k个所给字符串,求能构造出的个数. 题解: ...

  5. HDU 2825 Wireless Password ( Trie图 && 状态压缩DP )

    题意 : 输入n.m.k意思就是给你 m 个模式串,问你构建长度为 n 至少包含 k 个模式串的方案有多少种 分析 : ( 以下题解大多都是在和 POJ 2778 && POJ 162 ...

  6. HDU 2825 Wireless Password(AC自动机+DP)

    题目链接 做题, #include <cstdio> #include <string> #include <cstring> using namespace st ...

  7. HDU 2825 Wireless Password【AC自动机+DP】

    给m个单词,由这m个单词组成的一个新单词(两个单词可以重叠包含)长度为n,且新单词中包含的基本单词数目不少于k个.问这样的新单词共有多少个? m很小,用二进制表示新单词中包含基本单词的情况. 用m个单 ...

  8. [AC自己主动机+状压dp] hdu 2825 Wireless Password

    题意: 给n.m,k ,再给出m个单词 问长度为n的字符串.至少在m个单词中含有k个的组成方案有多少种. 思路: 因为m最大是10,所以能够採取状压的思想 首先建立trie图,在每一个单词的结束节点标 ...

  9. HDU 2825 Wireless Password(AC自动机 + 状压DP)题解

    题意:m个密码串,问你长度为n的至少含有k个不同密码串的密码有几个 思路:状压一下,在build的时候处理fail的时候要用 | 把所有的后缀都加上. 代码: #include<cmath> ...

随机推荐

  1. 深踩 AndroidStudio 缓存的坑

    本文记录的是今天在群里提到的昨天所踩的一个坑,有关 AndroidStudio 缓存的. 先说一下背景. 我负责的一个项目,对一个图表库有外部依赖.这个图表库是我在维护的,由于新功能在开发中,所以我就 ...

  2. 【bzoj3195】 Jxoi2012—奇怪的道路

    http://www.lydsy.com/JudgeOnline/problem.php?id=3195 (题目链接) 题意 一张$n$个点$m$条边的无向图,每个点度数为偶数,一个点只能向标号与它的 ...

  3. 单点登录(三)-----实战-----cas server 源码下载和部署

    我们在上一篇文章中使用的是4.0版本的cas,4.0版本的有发布好的war包可以直接使用,那如果我们要使用更新的版本怎么办呢? 就需要下载源码自己编辑打包了. 步骤如下: 版本选择 我们在cas的gi ...

  4. python之旅:并发编程之多线程

    一 threading模块介绍 multiprocess模块的完全模仿了threading模块的接口,二者在使用层面,有很大的相似性,因而不再详细介绍 官网链接:https://docs.python ...

  5. Linux上给php配置redis扩展

    说明,在项目开发中难免会遇到redis中,那我应该如何配置redis这样的一个扩展呢,看下面流程: 一.安装Redis PHP在安装redis扩展时,难免要看一下官网下载安装流程,链接如下: http ...

  6. ACF/PACF,残差白噪声的检验问题

    关于自相关.偏自相关: 一.自协方差和自相关系数       p阶自回归AR(p)       自协方差 r(t,s)=E[X(t)-EX(t)][X(s)-EX(s)]       自相关系数ACF ...

  7. Rancher Server HA的高可用部署实验-学习笔记

    转载于https://blog.csdn.net/csdn_duomaomao/article/details/78771731 Rancher Server HA的高可用部署实验-学习笔记 一.机器 ...

  8. [Linux]-Linux常用命令之文件解压

    不压缩方式压缩的文件需要不同的命令来解压缩,下面是Linux的各种文件解压命令. 对于.tar结尾的文件: tar -xf 对于.gz结尾的文件 : gzip -d all.gz gunzip all ...

  9. tf.nn.conv2d 参数介绍

    tf.nn.conv2d是TensorFlow里面实现卷积的函数,参考文档对它的介绍并不是很详细,实际上这是搭建卷积神经网络比较核心的一个方法,非常重要 tf.nn.conv2d(input, fil ...

  10. Java基础-面向对象第三大特性之多态(polymorphism )

    Java基础-面向对象第三大特性之多态(polymorphism) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.多态概述 多态是继封装,继承之后,面向对象的第三大特性,多态的 ...