题目链接:https://vjudge.net/problem/HDU-2825

Wireless Password

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 7733    Accepted Submission(s): 2509

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个单词的字符串有多少个?

题解:

1.把这m个单词插入到AC自动机中。

2.设dp[i][j][status]为:长度为i,到达j状态(AC自动机中的状态),且含有单词的信息为status(状态压缩)的字符串有多少个。

3.模拟在AC自动机上的跳动,求出dp数组。

代码如下:

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <string>
#include <set>
using namespace std;
typedef long long LL;
const double EPS = 1e-;
const int INF = 2e9;
const LL LNF = 9e18;
const int MOD = ;
const int MAXN = +; int num[<<], dp[][][<<]; struct Trie
{
const static int sz = , base = 'a';
int next[MAXN][sz], fail[MAXN], end[MAXN];
int root, L;
int newnode()
{
for(int i = ; i<sz; i++)
next[L][i] = -;
end[L++] = ;
return L-;
}
void init()
{
L = ;
root = newnode();
}
void insert(char buf[], int id)
{
int len = strlen(buf);
int now = root;
for(int i = ; i<len; i++)
{
if(next[now][buf[i]-base] == -) next[now][buf[i]-base] = newnode();
now = next[now][buf[i]-base];
}
end[now] |= (<<id);
}
void build()
{
queue<int>Q;
fail[root] = root;
for(int i = ; i<sz; i++)
{
if(next[root][i] == -) next[root][i] = root;
else fail[next[root][i]] = root, Q.push(next[root][i]);
}
while(!Q.empty())
{
int now = Q.front();
Q.pop();
end[now] |= end[fail[now]]; //当前串的后缀是否也包含单词
for(int i = ; i<sz; i++)
{
if(next[now][i] == -) next[now][i] = next[fail[now]][i];
else fail[next[now][i]] = next[fail[now]][i], Q.push(next[now][i]);
}
}
} int query(int n, int m, int k)
{
for(int i = ; i<=n; i++)
for(int j = ; j<L; j++)
for(int s = ; s<(<<m); s++)
dp[i][j][s] = ;
dp[][][] = ;
for(int i = ; i<n; i++) //模拟在AC自动机上的跳动
for(int j = ; j<L; j++)
for(int s = ; s<(<<m); s++)
{
if(dp[i][j][s]==) continue;
for(int p = ; p<sz; p++)
{
int newi = i+;
int newj = next[j][p];
int news = (s|end[newj]);
dp[newi][newj][news] += dp[i][j][s];
dp[newi][newj][news] %= MOD;
}
}
int ret = ;
for(int s = ; s<(<<m); s++)
{
if(num[s]<k) continue;
for(int i = ; i<L; i++)
ret = (ret+dp[n][i][s])%MOD;
}
return ret;
}
}; Trie ac;
char buf[];
int main()
{
for(int s = ; s<(<<); s++)
{
num[s] = ;
for(int i = ; i<; i++)
if(s&(<<i)) num[s]++;
} int n, m, k;
while(scanf("%d%d%d", &n,&m,&k)&&(n||m||k))
{
ac.init();
for(int i = ; i<m; i++)
{
scanf("%s", buf);
ac.insert(buf, i);
}
ac.build();
int ans = ac.query(n,m,k);
printf("%d\n", ans);
}
return ;
}

HDU2825 Wireless Password —— AC自动机 + 状压DP的更多相关文章

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

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

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

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

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

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

  4. hdu_2825_Wireless Password(AC自动机+状压DP)

    题目链接:hdu_2825_Wireless Password 题意: 给你m个串,问长度为n至少含k个串的字符串有多少个 题解: 设dp[i][j][k]表示考虑到长度为i,第j个自动机的节点,含有 ...

  5. hdu 2825 aC自动机+状压dp

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

  6. BZOJ1559 [JSOI2009]密码 【AC自动机 + 状压dp】

    题目链接 BZOJ1559 题解 考虑到这是一个包含子串的问题,而且子串非常少,我们考虑\(AC\)自动机上的状压\(dp\) 设\(f[i][j][s]\)表示长度为\(i\)的串,匹配到了\(AC ...

  7. HDU 3247 Resource Archiver(AC自动机 + 状压DP + bfs预处理)题解

    题意:目标串n( <= 10)个,病毒串m( < 1000)个,问包含所有目标串无病毒串的最小长度 思路:貌似是个简单的状压DP + AC自动机,但是发现dp[1 << n][ ...

  8. zoj3545Rescue the Rabbit (AC自动机+状压dp+滚动数组)

    Time Limit: 10 Seconds      Memory Limit: 65536 KB Dr. X is a biologist, who likes rabbits very much ...

  9. hdu 4057--Rescue the Rabbit(AC自动机+状压DP)

    题目链接 Problem Description Dr. X is a biologist, who likes rabbits very much and can do everything for ...

随机推荐

  1. [转]Windows10内置Linux子系统初体验

    Windows10内置Linux子系统初体验 https://www.jianshu.com/p/bc38ed12da1d

  2. [java面试]关于多态性的理解

    执行时多态性是面向对象程序设计代码重用的一个最强大机制.Java多态性的概念也能够被说成"一个接口.多个方法".Java实现执行时多态性的基础是动态方法调度,它是一种在执行时而不是 ...

  3. FMSC 使用理解

    看了非常长时间 FMSC资料 都说的模糊的. 事实上非常easy: fsmc就是为了扩展内存的,如我们在stm32芯片外加入一个sram芯片.那么我们仅仅须要把 sram芯片的地址线和数据线和stm3 ...

  4. ionic 调试 "死亡白屏"

    死亡白屏(White Screen of Death) 我想“死亡白屏”应该是不需要解释的,开发过ionic app的童鞋应该都有遇到过,这里解释以防读者没有听说过:“可能在浏览器中调试时一切正常,当 ...

  5. eclipse svn插件 删除原账号信息重新登录

    1.通过删除SVN客户端的账号配置文件    1)查看你的Eclipse中使用的是什么SVN Interface(中文:svn接口)windows > preference > Team ...

  6. Java实现分布式锁方式

    1.数据库乐观锁 2.redis 3.zookeeper

  7. C语言 结构体作为函数的参数

    1)使用结构体变量作为函数的参数 使用结构体变量作为函数的实参时,采用的是值传递,会将结构体变量所占内存单元的内容全部顺序传递给形参,形参必须是同类型的结构体变量 demo: # include &l ...

  8. Android模糊效果总结

    1. 软件模糊 用软件的方法.利用cpu计算,无sdk版本号要求. 效果图: 关键模糊代码 github链接 原文 链接 译文 链接 演示样例 代码 本文地址 :http://blog.csdn.ne ...

  9. python 基础 1.2--pycharm 的安装及使用

    一. windows 先安装pycharm. PyCharm是一种Python IDE,带有一整套可以帮助用户在使用Python语言开发时提高其效率的工具,其提供了一个带编码补全,代码片段,支持代码折 ...

  10. 【BZOJ3956】Count 主席树+单调栈

    [BZOJ3956]Count Description Input Output Sample Input 3 2 0 2 1 2 1 1 1 3 Sample Output 0 3 HINT M,N ...