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. MySQL创建一个固定频率执行且自定义"开始"时间的定时任务event

    drop event if exists evt_test;create event evt_teston schedule every 10 SECOND  -- 每10秒执行一次(second可以 ...

  2. office------------word邮件合并(word2016版)

    虽然本人是学计算机的,但是office技能很一般,最近工作中用到了邮件合并这一功能,记录下来与大家分享. 我用到的邮件合并就是word中定好模板,从excel中批量导入数据,现实生活中,在录取通知书打 ...

  3. bzoj 3207: 花神的嘲讽计划Ⅰ

    Description 背景 花神是神,一大癖好就是嘲讽大J,举例如下: "哎你傻不傻的![hqz:大笨J]" "这道题又被J屎过了!!" "J这程序 ...

  4. java获取properties配置文件值

    package me.ilt.Blog.util; import java.io.File; import java.io.FileInputStream; import java.io.IOExce ...

  5. NumPy学习笔记 三 股票价格

    NumPy学习笔记 三 股票价格 <NumPy学习笔记>系列将记录学习NumPy过程中的动手笔记,前期的参考书是<Python数据分析基础教程 NumPy学习指南>第二版.&l ...

  6. base64格式图片转换为FormData对象进行上传

    原理:理由ArrayBuffer.Blob和FormData var base64String = /*base64图片串*/; //这里对base64串进行操作,去掉url头,并转换为byte va ...

  7. java推送数据到app--极光推送

    之前项目有用到需要把数据推送到app端 采用的是极光推送 特此把工具类和pom.xml需要的jar整理如下 pom.xml需要jar如下 <!-- 极光推送 --> <depende ...

  8. 来一轮带注释的demo,彻底搞懂javascript中的replace函数

    javascript这门语言一直就像一位带着面纱的美女,总是看不清,摸不透,一直专注服务器端,也从来没有特别重视过,直到最近几年,javascript越来越重要,越来越通用.最近和前端走的比较近,借此 ...

  9. 【自问自答】关于 Swift 的几个疑问

    感觉自己给自己释疑,也是一个极为有趣的过程.这次,我还新增了"猜想"一栏,来尝试回答一些暂时没有足够资料支撑的问题. Swift 版本是:4.0.3.不同版本的 Swift,可能无 ...

  10. HashMap与ConcurrentHashMap

    从JDK1.2起,就有了HashMap,正如前一篇文章所说,HashMap不是线程安全的,因此多线程操作时需要格外小心. 在JDK1.5中,伟大的Doug Lea给我们带来了concurrent包,从 ...