题目链接: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. c++11 左值引用、右值引用

    c++11 左值引用.右值引用 #define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <string> #i ...

  2. IBatisNet 缓存使用

    参考:http://www.cnblogs.com/xiaogangqq123/archive/2011/06/30/2094905.html <?xml version="1.0&q ...

  3. 学习Spring Boot:(七)集成Mybatis

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

  4. 4 MySQL程序概述(包含mysql配置文件配置原理)-学习笔记

    以下参考MySQL5.5官方简体中文参考手册完美版--用于自学复习使用 4.1 程序概述 MySQL AB提供了几种类型的程序:一般放在/安装目录/bin下 1 MYSQL服务器和服务器启动脚本 my ...

  5. 解题:APIO 2012 派遣

    题面 以报酬为标准维护一个大根堆,从根节点往上合并,每次踢掉若干人直到花费合法后更新答案 #include<cstdio> #include<cstring> #include ...

  6. E. Turn Off The TV Educational Codeforces Round 29

    http://codeforces.com/contest/863/problem/E 注意细节 #include <cstdio> #include <cstdlib> #i ...

  7. matlab绿色版本合集

    网上找的matlab绿色版本合集链接https://pan.baidu.com/s/1gfDyIo7     密码:pxrs

  8. C++实现两个大整数的相加(考虑到负数异常情况)

    实现两个大整数的相加,首先应该排除直接使用int和long long的方法,这些方法很容易溢出,这里为了方便(是否可以使用更精简的结构存储?)采用char来存储整数,整体思路如下: 1. 对于整数n和 ...

  9. 【Asp.net入门3-02】使用jQuery-jQuery 入门

    下面的几小节将介绍jQuery的基础知识.如前所述,不可能仅仅通过一章的内容详细介绍jQuery, 但可以向你说明如何对HTML文档中的内容执行简单的操作,以及更重要的,如何逐步实现本书其他 部分的示 ...

  10. pyqt4_应用例子(计算器,对话框,进度条,日历等等)

    sklearn实战-乳腺癌细胞数据挖掘(博客主亲自录制视频教程) https://study.163.com/course/introduction.htm?courseId=1005269003&a ...