题目连接: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. 查找linux系统下的端口被占用进程的两种方法 【转】

    在linux下开发时,你的软件可能要使用某一个端口,或者想查找某一个端口是否被占用.需要怎么做呢??这的确是一个比较烦恼的问题,我也此为这个苦恼过.但是通过查找man手册,还是同事的交流.总结出来两种 ...

  2. Scrapy使用RabbitMQ做任务队列

    前言 一个月没更博客了,这个月也搞了不少东西,但是公司对保密性要求挺高,很多东西都没有办法写出来 想来想去,还是写一篇最近写Scrapy中遇到的跳转问题 如果你的业务需求是遇到301/302/303跳 ...

  3. Array.apply(null, {length: 2}) 的理解

    // apply 的第二参数通常是数组 但是也可以传递类数组对象{length: 2}console.log(Array.apply(null, {length: 2})) // [undefined ...

  4. 区间合并 C++

    #include <iostream> #include <vector> #include <algorithm> using namespace std; ty ...

  5. Redis-4.X 版本 Redis Cluster集群 (一)

    一 创建redis cluster 集群前提条件: 1 ) 每个redis node 节点采用相同的硬件配置,相同的密码. 2 ) 每个节点必须开启的参数: cluster-enabled yes # ...

  6. 基础练习(上) - 蓝桥杯(Python实现)

    闰年判断: 题目: 资源限制 时间限制:1.0s 内存限制:256.0MB 问题描述 给定一个年份,判断这一年是不是闰年. 当以下情况之一满足时,这一年是闰年: 1. 年份是4的倍数而不是100的倍数 ...

  7. cursor pin s和cursor pin s wait on x

    1.cursor pin s是一个共享锁,一般情况下是因为发生在SQL短时间内大量执行 案例:在生产库中,突然出现大量的cursor pin s的等待,询问是否有动作后,同事说有编译存储过程(被误导了 ...

  8. git创建分支并关联远程分支

    1.新建本地分支: 如图,再输入你的分支名字,然后选择从哪个远程分支拉代码,如选择master 至此本地分支创建完成. 2.关联远程分支: (1).先输入git branch -vv,看看分支与远程分 ...

  9. postgres模糊匹配大杀器

    ArteryBase-模糊匹配大杀器 问题背景 随着pg越来越强大,abase目前已经升级到5.0(postgresql10.4),目前abase5.0继承了全文检索插件(zhparser),使用全文 ...

  10. Ubuntu20.04 安装火狐开发者版本(水狐)步骤

    1. 从Mozilla Firefox Developer Edition webpage下载. 2. 将下载的"tar.bz2"文件解压到指定目录, 例如/opt/firefox ...