pid=2825">http://acm.hdu.edu.cn/showproblem.php?

pid=2825

Wireless Password
Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 4560    Accepted Submission(s): 1381
Problem 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
 
Source
 

题意:

给出m个模式串。要求构造一长度为n的文本串,至少包含k种模式串,求有多少种可能的模式串。

分析:

m个模式串构建AC自己主动机。然后要在这AC自己主动机中走n步。至少经过k个单词结点。由于m<=10,显然能够用状压表示已经有哪几个单词结点。用dp[i][j][k]表示走了i步到AC自己主动机中的第j个结点,单词状态为k。由计数原理可推出状态转移方程:dp[i][j][k]=sum(dp[i-1][last_j][last_k]),last_j表示能够抵达第j个结点的上一个结点。last_k表示上一步的状态;由于第i步仅仅和第i-1步有关。所以能够用滚动数组优化空间。

/*
*
* Author : fcbruce <fcbruce8964@gmail.com>
*
* Time : Thu 20 Nov 2014 10:01:45 AM CST
*
*/
#include <cstdio>
#include <iostream>
#include <sstream>
#include <cstdlib>
#include <algorithm>
#include <ctime>
#include <cctype>
#include <cmath>
#include <string>
#include <cstring>
#include <stack>
#include <queue>
#include <list>
#include <vector>
#include <map>
#include <set>
#define sqr(x) ((x)*(x))
#define LL long long
#define itn int
#define INF 0x3f3f3f3f
#define PI 3.1415926535897932384626
#define eps 1e-10 #ifdef _WIN32
#define lld "%I64d"
#else
#define lld "%lld"
#endif #define maxm
#define maxn 255 using namespace std; const int mod = 20090717; int dp[2][maxn][1024]; inline int add(int a,int b)
{
return (a+b)%mod;
} int q[maxn]; const int maxsize = 26;
struct ACauto
{
int ch[maxn][maxsize];
int val[maxn],nex[maxn],last[maxn];
int sz; ACauto()
{
memset(ch[0],0,sizeof ch[0]);
val[0]=0;
sz=1;
} void clear()
{
memset(ch[0],0,sizeof ch[0]);
val[0]=0;
sz=1;
} int idx(char c)
{
return c-'a';
} void insert(const char *s,int v)
{
int u=0;
for (int i=0;s[i]!='\0';i++)
{
int c=idx(s[i]);
if (ch[u][c]==0)
{
memset(ch[sz],0,sizeof ch[sz]);
val[sz]=0;
ch[u][c]=sz++;
}
u=ch[u][c];
}
val[u]=v;
} void get_fail()
{
int f=0,r=-1;
nex[0]=0;
for (int c=0;c<maxsize;c++)
{
int u=ch[0][c];
if (u!=0)
{
nex[u]=0;
q[++r]=u;
last[u]=0;
}
} while (f<=r)
{
int x=q[f++];
for (int c=0;c<maxsize;c++)
{
int u=ch[x][c];
if (u==0)
{
ch[x][c]=ch[nex[x]][c];
continue;
}
q[++r]=u;
int v=nex[x];
nex[u]=ch[v][c];
val[u]|=val[nex[u]];
}
}
} int calc(int x)
{
int cnt=0;
for (int i=0;i<32;i++)
if (x&(1<<i)) cnt++;
return cnt;
} int DP(int l,int m,int k)
{
memset(dp,0,sizeof dp);
dp[0][0][0]=1;
int x=1;
for (int i=0;i<l;i++,x^=1)
{
memset(dp[x],0,sizeof dp[x]);
for (int j=0;j<sz;j++)
{
for (int s=0;s<m;s++)
{
if (dp[x^1][j][s]==0) continue;
for (int c=0;c<maxsize;c++)
{
int &cur=dp[x][ch[j][c]][s|val[ch[j][c]]];
cur=add(cur,dp[x^1][j][s]);
}
}
}
} int total=0; for (int i=0;i<m;i++)
{
if (calc(i)<k) continue;
for (int j=0;j<sz;j++)
total=add(total,dp[x^1][j][i]);
} return total;
}
}acauto; char str[16]; int main()
{
#ifdef FCBRUCE
freopen("/home/fcbruce/code/t","r",stdin);
#endif // FCBRUCE int n,m,k; while (scanf("%d%d%d",&n,&m,&k),n||m||k)
{
acauto.clear();
for (int i=0;i<m;i++)
{
scanf("%s",str);
acauto.insert(str,1<<i);
} acauto.get_fail(); printf("%d\n",acauto.DP(n,1<<m,k));
} return 0;
}

HDU 2825 Wireless Password (AC自己主动机,DP)的更多相关文章

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

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

  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 2457 DNA repair (ac自己主动机+dp)

    题目大意: 改动文本串的上的字符,使之不出现上面出现的串.问最少改动多少个. 思路分析: dp[i][j]表示如今 i 个字符改变成了字典树上的 j 节点. 然后顺着自己主动机一直转移方程. 注意合法 ...

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

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

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

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

  6. POJ 3691 &amp; HDU 2457 DNA repair (AC自己主动机,DP)

    http://poj.org/problem?id=3691 http://acm.hdu.edu.cn/showproblem.php?pid=2457 DNA repair Time Limit: ...

  7. HDU 2896 病毒侵袭 (AC自己主动机)

    pid=2896">http://acm.hdu.edu.cn/showproblem.php?pid=2896 病毒侵袭 Time Limit: 2000/1000 MS (Java ...

  8. hdu 2222 Keywords Search ac自己主动机

    点击打开链接题目链接 Keywords Search Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Ja ...

  9. HDU 2896 病毒侵袭 AC自己主动机题解

    本题是在text里面查找key word的增强版.由于这里有多个text. 那么就不能够简单把Trie的叶子标志记录改动成-1进行加速了,能够使用其它技术.我直接使用个vis数组记录已经訪问过的节点, ...

随机推荐

  1. LeetCode(104) Maximum Depth of Binary Tree

    题目 Given a binary tree, find its maximum depth. The maximum depth is the number of nodes along the l ...

  2. 图论:POJ2186-Popular Cows (求强连通分量)

    Popular Cows Description Every cow's dream is to become the most popular cow in the herd. In a herd ...

  3. Django模板语言中的自定义方法filter过滤器实现web网页的瀑布流

    模板语言自定义方法介绍 自定义方法注意事项 Django中有simple_tag 和 filter 两种自定义方法,之前也提到过,需要注意的是 扩展目录名称必须是templatetags templa ...

  4. PYDay4-基本数据类型、字符串、元组、列表、字典

    1.关于编码: utf-8 与gbk都是对Unicode 编码的简化,utf-8是针对所有语言的精简,gbk是针对中文的精简 py3默认字符集为UTF-8,取消了Unicode字符集,如后面的编程过程 ...

  5. python第三方库之openpyxl(1)

    python第三方库之openpyxl(1) 简介 Openpyxl是一个用于读写Excel 2010 xlsx/xlsm/xltx/xltm文件的Python库,其功能非常强大.Excel表格可以理 ...

  6. 【转】DCOM远程调用权限设置

    原文:https://blog.csdn.net/ervinsas/article/details/36424127 最近几天被搞得焦头烂额,由于DCOM客户端程序是在32位系统下开发的,调试时DCO ...

  7. "sort open failed +1 no such file or directory"解决方

    GNU的sort也认老式字段规格: +n.m. 但是字段和字符都从0开始计, 例如-k3 -k2可以等效为+2 -3 +1 -2. 目前使用的sort+和-必须成对使用, 只用+就会报错说”sort: ...

  8. HackerRank# Stock Maximize

    原题地址 不知道为什么要用动态规划做,明明是扫几遍就行了啊 HackerRank上的题目特别喜欢long long类型啊,不用就爆.. 代码: #include <cmath> #incl ...

  9. [luoguP2495] [SDOI2011]消耗战(DP + 虚树)

    传送门 明显虚树. 别的题解里都是这样说的. 先不考虑虚树,假设只有一组询问,该如何dp? f[u]表示把子树u中所有的有资源的节点都切掉的最优解 如果节点u需要切掉了话,$f[u]=val[u]$ ...

  10. C 语言中的 feof()函数

    功能: feof 是 C 语言标准库函数函数,其原型在 stdio.h 中,其功能是检测流上的文件结束符,如果文件结束,则返回非0值,否则返回0,文件结束符只能被 clearerr() 清除. 用法: ...