题目链接: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. 学习Spring Boot:(七)集成Mybatis

    前面都是用的是spring data JPA,现在学习下Mybatis,而且现在Mybatis也像JPA那样支持注解形式了,也非常方便,学习一下. 数据库 mysql 5.7 添加依赖 在pom文件中 ...

  2. 使用telnet访问百度

    这里主要是玩一下http协议,查看http的header. 1.输入命令telnet访问百度 # telnet www.baidu.com 80 Trying 220.181.112.244... C ...

  3. bzoj 1814: Ural 1519 Formula 1 插头dp经典题

    用的括号序列,听说比较快. 然并不会预处理,只会每回暴力找匹配的括号. #include<iostream> #include<cstdio> #include<cstr ...

  4. (转)解决dubbox-demo-provider.xml报错的问题:提示Failed to read schema document

    背景:在eclipse项目中,经常会遇到xml文件提示找不到.xsd文件的情况.很有必要弄清xsd文件的加载过程! 1 解决过程 dubbo-demo-provider导入eclipse后dubbox ...

  5. 2:spring中的@resource

    @Resource 其实是spring里面的注解注入. @Resource(这个注解属于J2EE的),默认安照名称进行装配,名称可以通过name属性进行指定, 如果没有指定name属性,当注解写在字段 ...

  6. salt源码安装

    salt是什么? 一种全新的基础设施管理方式,部署轻松,在几分钟内可运行起来,扩展性好,很容易管理上万台服务器,速度够快,服务器之间秒级通讯. salt底层采用动态的连接总线, 使其可以用于编配, 远 ...

  7. SIFT算法学习

    几个关于SIFT算法的blog,写的很好,链接学习一下 小北的家谈谈SIFT.PCA-SIFT.SURF及我的一点思考http://blog.csdn.net/ijuliet/article/deta ...

  8. 修改const保护的值

    先看代码: #include <stdio.h> void main() { const int num = 10; int *a = (int *)(void *)&num; / ...

  9. Docker swarm 使用服务编排部署lnmp

    一.简介 目的:在Docker Swarm集群中,使用stack服务编排搭建lnmp来部署WordPress 使用私有仓库的nginx和php镜像 mysql使用dockerhup最新镜像 使用nfs ...

  10. linux(ubuntu) 常用指令

    1.新建文件夹 mkdir mkdir test 2.进入文件夹 cd cd test 3.创建/修改文件 vim vim a.txt 如果不存在a.txt,就会新增a.txt; 如果存在,则修改 先 ...