Description

Liyuan lives in a old apartment. One day, he suddenly found that there was a wireless network in the building. Liyuan did not know the password of the network, but he got some important information from his neighbor. He knew the password consists only of lowercase letters 'a'-'z', and he knew the length of the password. Furthermore, he got a magic word set, and his neighbor told him that the password included at least k words of the magic word set (the k words in the password possibly overlapping).

For instance, say that you know that the password is 3 characters long, and the magic word set includes 'she' and 'he'. Then the possible password is only 'she'.

Liyuan wants to know whether the information is enough to reduce the number of possible passwords. To answer this, please help him write a program that determines the number of possible passwords.

 

Input

There will be several data sets. Each data set will begin with a line with three integers n m k. n is the length of the password (1<=n<=25), m is the number of the words in the magic word set(0<=m<=10), and the number k denotes that the password included at least k words of the magic set. This is followed by m lines, each containing a word of the magic set, each word consists of between 1 and 10 lowercase letters 'a'-'z'. End of input will be marked by a line with n=0 m=0 k=0, which should not be processed.
 

Output

For each test case, please output the number of possible passwords MOD 20090717.
 

Sample Input

10 2 2
hello world
4 1 1
icpc
10 0 0
0 0 0
 

Sample Output

2 1 14195065
 
dp
#include<queue>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std; const int LO=,NU=,MOD=;
inline int f(char u){
return u-'a';
}
inline void M(int &a){
if (a>=MOD) a-=MOD;
}
struct tree{
int f;
int q;
int t[LO];
int v[LO];
}t[NU];
int n,m,p,num;
char s[];
bool us[NU];
queue <int> q;
int dp[][NU][<<];
inline int dfs(int x){
if (x==) return ;
if (us[x]) return t[x].q;
us[x]=;
return t[x].q|=dfs(t[x].f);
}
inline void in(int x){
int p=,l,m=strlen(s);
for (register int i=;i<m;i++){
l=f(s[i]);
if (!t[p].t[l]) t[p].t[l]=++num;
p=t[p].t[l];
}
t[p].q=<<x;
}
inline void mafa(){
register int i;int k,p;
q.push();t[].f=;
while(!q.empty()){
k=q.front();q.pop();
for (i=;i<LO;i++)
if (t[k].t[i]){
p=t[k].f;
while((!t[p].t[i])&&p) p=t[p].f;
t[t[k].t[i]].f=(k==p)?:t[p].t[i];
q.push(t[k].t[i]);
}
}
}
int main(){
register int i,j,k,l;int u;int ans;
while(scanf("%d%d%d",&n,&m,&p)){
if (!(n|m|p)) break;
num=u=ans=;
for (i=;i<m;i++){
scanf("%s",s);
in(i);
}
mafa();
for (i=;i<=num;i++) us[i]=;
for (i=;i<=num;i++)
t[i].q|=dfs(i);
dp[][][]=;
for (i=;i<=num;i++)
for (j=;j<LO;j++){
if (!t[i].t[j]){
u=t[i].f;
while(!t[u].t[j]&&u) u=t[u].f;
u=t[u].t[j];
}else u=t[i].t[j];
t[i].v[j]=u;
}
for (i=;i<n;i++)
for (j=;j<=num;j++)
for (k=;k<(<<m);k++)
if (dp[i][j][k]!=)
for (l=;l<LO;l++){
u=k|t[t[j].v[l]].q;
M(dp[i+][t[j].v[l]][u]+=dp[i][j][k]);
}
for (i=;i<=num;i++)
for (k=;k<(<<m);k++){
u=;
for (j=;j<m;j++) if (k&(<<j)) u++;
if (u>=p) M(ans+=dp[n][i][k]);
}
printf("%d\n",ans);
for (i=;i<=n;i++)
for (j=;j<=num;j++)
for (k=;k<(<<m);k++) dp[i][j][k]=;
for (i=;i<=num;i++)
for (j=;j<LO;j++) t[i].t[j]=t[i].v[j]=;
for (i=;i<=num;i++) t[i].q=t[i].f=;
}
}

HDU2825 Wireless Password的更多相关文章

  1. HDU2825 Wireless Password 【AC自动机】【状压DP】

    HDU2825 Wireless Password Problem Description Liyuan lives in a old apartment. One day, he suddenly ...

  2. HDU2825 Wireless Password —— AC自动机 + 状压DP

    题目链接:https://vjudge.net/problem/HDU-2825 Wireless Password Time Limit: 2000/1000 MS (Java/Others)    ...

  3. hdu2825 Wireless Password(AC自动机+状压dp)

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission ...

  4. 【AC自动机】【状压dp】hdu2825 Wireless Password

    f(i,j,S)表示当前字符串总长度为i,dp到AC自动机第j个结点,单词集合为S时的方案数. 要注意有点卡常数,注意代码里的注释. #include<cstdio> #include&l ...

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

    题目大意:给一系列字符串,用小写字母构造出长度为n的至少包含k个字符串的字符串,求能构造出的个数. 题目分析:在AC自动机上走n步,至少经过k个单词节点,求有多少种走法. 代码如下: # includ ...

  6. HDU2825 Wireless Password(AC自动机+状压DP)

    题目问长度n至少包含k个咒语的字符串有多少个.也是比较入门的题.. dp[i][j][S]表示长度i(在自动机上转移k步)且后缀状态为自动机上第j个结点且当前包含咒语集合为S的方案数 dp[0][0] ...

  7. 【HDU2825】Wireless Password (AC自动机+状压DP)

    Wireless Password Time Limit: 1000MS   Memory Limit: 32768KB   64bit IO Format: %I64d & %I64u De ...

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

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

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

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

随机推荐

  1. 【java】扫描流Scanner接收输入示例

    多用Scanner少用InputStream 多用BufferedReader少用Reader 多用PrintStream少用OutputStream 多用PrintWriter少用Writer pa ...

  2. Kafka+Storm写入Hbase和HDFS

    1.Storm整合Kafka 使用Kafka作为数据源,起到缓冲的作用 // 配置Kafka订阅的Topic,以及zookeeper中数据节点目录和名字 String zks = KafkaPrope ...

  3. lesson - 3 ls /cd /path /alias /快捷键

    内容概要: 1. 命令ls -l   详细信息-a  查看隐藏的文件或目录-d   只看目录本身,不列出目录下面的文件和目录-t 以时间先后排序 2  目录结构/bin, /sbin, /usr/bi ...

  4. Linux发行版 CentOS6.5下删除分区操作

    本文地址http://comexchan.cnblogs.com/,作者Comex Chan,尊重知识产权,转载请注明出处,谢谢!   有时候,发现分区分错了.需要删除分区,只需按照分区的步骤逆向操作 ...

  5. 关于md5的使用方法

    本周工作,学习中用到了,md5. 在我们需要用到md5密码的时候,可以使用: System.Web.Security.FormsAuthentication.HashPasswordForStorin ...

  6. SQL 多列合并一列

    select rtrim(姓)+ rtrim(名) as 姓名 from tb

  7. 初识BASH SHELL

    什么是Shell shell翻译成中文就是"壳"的意思.简单来说就是shell是计算机用户与操作系统内核进行"沟通"的一种工具.Windows系统中有power ...

  8. vs2017中生成.Net Standard Libarary的Nuget Package

    场景: Project A 对Project B存在 project to project reference.这种场景下必须为两者都生成nuget package.这样在load Project A ...

  9. ES6 modules 详解

    概述 历史上,JavaScript 一直没有模块(module)体系,无法将一个大程序拆分成互相依赖的小文件,再用简单的方法拼装起来.其他语言都有这项功能,比如 Ruby 的require.Pytho ...

  10. StringMVC @RequestParam属性

    1.jsp: <a href="springmvc/testRequestParam?username=allen&age=sss">test RequsetP ...