题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=2825

题意:给一些字符串,构造出长度为n的字符串,它至少包含k个所给字符串,求能构造出的个数。

题解:

对end[]节点标记数组进行改动,用二进制下第几位表示即为包含第几个给定子串;

状态转移方程为:dp[i+1][x][k|end[x]]=(dp[i+1][x][k|end[x]]+dp[i][j][k])%mod;(没懂为什么要用‘ | ’ ,等搞明白了在更新吧,,)

dp[i][j][l] 表示长度 i 在第j个结点且当前包含字符串集合为 l 的方案数;

  1 #include<bits/stdc++.h>
2 #define ll long long
3 using namespace std;
4
5 const ll mod=20090717;
6 const ll maxn = 111;
7 ll ans=0;
8 ll sum[1100];
9 ll n,m,k;
10
11 struct tire{
12 ll nxt[maxn][30],fail[maxn],end[maxn],tot,root,vis[maxn];
13 ll newNode(){
14 for(ll i=0;i<26;i++) nxt[tot][i] = -1;
15 end[tot++] = 0;
16 return tot-1;
17 }
18 void Init(){
19 tot = 0;
20 root = newNode();
21 memset(dp,0,sizeof(dp));
22 }
23 void Insert(char *buf,ll id){
24 ll len = strlen(buf),i,u = root;
25 for(i=0;i<len;i++){
26 ll x = buf[i]-'a';
27 if(nxt[u][x]==-1) nxt[u][x] = newNode();
28 u = nxt[u][x];
29 }
30 end[u] |= 1<<id;
31 }
32 void build(){
33 queue <ll> q;
34 fail[root] = root;
35 for(ll i=0;i<26;i++){
36 if(nxt[root][i]==-1) nxt[root][i] = root;
37 else{
38 fail[nxt[root][i]] = root;
39 q.push(nxt[root][i]);
40 }
41 }
42 while(!q.empty()){
43 ll now = q.front();
44 q.pop();
45 for(ll i=0;i<26;i++){
46 if(nxt[now][i]==-1) nxt[now][i] = nxt[fail[now]][i];
47 else{
48 fail[nxt[now][i]] = nxt[fail[now]][i];
49 q.push(nxt[now][i]);
50 }
51 }
52 end[now]|=end[fail[now]];
53 }
54 }
55 ll dp[30][111][1<<10];
56 void solve(){
57 dp[0][0][0]=1;
58 for(ll i=0;i<n;i++){
59 for(ll j=0;j<tot;j++){
60 for(ll k=0;k<(1<<m);k++){
61 if(dp[i][j][k]){
62 for(ll u=0;u<26;u++){
63 ll x=nxt[j][u];
64 dp[i+1][x][k|end[x]]+=dp[i][j][k];
65 dp[i+1][x][k|end[x]]%=mod;
66 }
67 }
68 }
69 }
70 }
71 ans=0;
72 for(ll i=0;i<tot;i++){
73 for(ll j=0;j<(1<<m);j++){
74 if(dp[n][i][j]&&sum[j]>=k) ans=(ans+dp[n][i][j])%mod;
75 }
76 }
77 cout<<ans<<endl;
78 }
79 }ac;
80
81 char s1[maxn];
82
83 int main()
84 {
85 for(ll i=0;i<(1<<10);i++){
86 for(ll j=0;j<10;j++){
87 if(i&(1<<j)) sum[i]++;
88 }
89 }
90 while(cin>>n>>m>>k){
91 if(!n&&!m&&!k) break;
92 ac.Init();
93 for(ll i=0;i<m;i++){
94 cin>>s1;
95 ac.Insert(s1,i);
96 }
97 ac.build();
98 ac.solve();
99 }
100 return 0;
101 }

HDU - 2825 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. 【HDU2825】Wireless Password (AC自动机+状压DP)

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. Redis的sentinel(哨兵)部署

    1.准备文件 1.解压redis-4.0.1.tar.gz的redis文件 2.新建目录 redis-cluster以及子目录 master-6379 slave-7000 slave-7001 3. ...

  2. FastApi 进阶

    前言 终于有了第一个使用 FastApi 编写的线上服务, 在开发的过程中还是遇到了些问题, 这里记录一下 正文 目录结构 我们知道, FastApi 的启动方式推荐使用 uvicorn, 其启动方式 ...

  3. 【MyBatis】MyBatis 缓存

    MyBatis 缓存 文章源码 什么是缓存 像大多数的持久化框架一样,MyBatis 也提供了缓存策略,通过缓存策略来减少数据库的查询次数,从而提高性能. Mybatis 中缓存分为一级缓存,二级缓存 ...

  4. LeetCode394 字符串解码

    给定一个经过编码的字符串,返回它解码后的字符串. 编码规则为: k[encoded_string],表示其中方括号内部的 encoded_string 正好重复 k 次.注意 k 保证为正整数. 你可 ...

  5. Docker学习笔记之基本命令使用

    测试的环境为Ubuntu1804. 1. search命令搜索镜像 sudo docker search centos 搜索centos相关的镜像,可以看到第一个最多星的的centos是官方的镜像,而 ...

  6. 单片机—Arduino UNO-R3—学习笔记002

    led控制 本篇主要介绍Arduino数字引脚及相关函数,通过数字I/O输出控制板载LED灯亮灭状态(数字引脚13). 数字信号是以0.1表示的电平不连续变化的信号,也就是以二进制的形式表示的信号. ...

  7. oracle 存储过程和包的权限

    GRANT CREATE ANY PROCEDURE TO MONKEY --創建,查看,替換的權限 GRANT EXECUTE ANY PROCEDURE TO MONKEY --執行和查看的權限 ...

  8. Poj-P3468题解【线段树】

    本文为原创,转载请注明:http://www.cnblogs.com/kylewilson/ 题目出处: http://poj.org/problem?id=3468 题目描述: 给N个数A1, A2 ...

  9. 利用sklearn进行字典&文本的特征提取

    写在前面 这篇博客主要内容: 应用DictVectorizer实现对类别特征进行数值化.离散化 应用CountVectorizer实现对文本特征进行数值化 特征提取API sklearn.featur ...

  10. 前端知识(一)03 初识 ECMAScript 6-谷粒学院

    目录 一.ECMAScript 6 1.什么是 ECMAScript 6 2.ECMAScript 和 JavaScript 的关系 二.基本语法 1.let声明变量 2.const声明常量(只读变量 ...