题意:

给n。m,k ,再给出m个单词

问长度为n的字符串。至少在m个单词中含有k个的组成方案有多少种。

思路:

因为m最大是10,所以能够採取状压的思想

首先建立trie图,在每一个单词的结束节点标记一个mark=(1<<id),id为单词的编号

然后须要注意的,对于每一个节点,应该顺着fail指针遍历一遍,

把全部的mark取一个并集。

由于就是假设单词出现包括的话,比方 she和he 我拿了she,事实上等于两个都拿了。

dp[i][j][k]  i步在节点j状态k的方案数

然后就是一个四重循环了

应该是非常好理解的

最后遍历在n步时,各个节点。然后判一下状态是否里面拿了不少于k个物品的个数

做一个累加就是答案了!

做dp的时候 顺便滚动了一下

代码:

#include"cstdlib"
#include"cstdio"
#include"cstring"
#include"cmath"
#include"queue"
#include"algorithm"
#include"iostream"
#include"map"
#include"string"
#define inf 9999999
#define mod 20090717
using namespace std;
int triecont;
struct trie
{
int mark,id;
trie *next[27],*fail;
trie()
{
memset(next,0,sizeof(next));
fail=NULL;
mark=id=0;
}
};
trie *root,*node[123];
void init(char *v,int k)
{
trie *p=root;
for(int i=0; v[i]; i++)
{
int tep=v[i]-'a';
if(p->next[tep]==NULL)
{
p->next[tep]=new trie();
node[triecont]=p->next[tep];
p->next[tep]->id=triecont++;
}
p=p->next[tep];
}
p->mark|=(1<<k);
}
void getac()
{
queue<trie*>q;
q.push(root);
while(!q.empty())
{
trie *p;
p=q.front();
q.pop();
for(int i=0; i<26; i++)
{
if(p->next[i]==NULL)
{
if(p==root) p->next[i]=root;
else p->next[i]=p->fail->next[i];
}
else
{
if(p==root) p->next[i]->fail=root;
else p->next[i]->fail=p->fail->next[i];
q.push(p->next[i]);
trie *tep=p->next[i];
if(p!=root) p->next[i]->mark|=p->next[i]->fail->mark;
}
}
}
}
int judge(int x)
{
int ans=0;
for(int i=0; i<10; i++)
{
if(x&(1<<i)) ans++;
}
return ans;
}
__int64 dp[2][105][1025];
int main()
{
int n,m,num;
while(scanf("%d%d%d",&n,&m,&num),(n+m+num))
{
memset(node,0,sizeof(node));
triecont=0;
root=new trie();
node[triecont]=root;
root->id=triecont++;
if(num>m)
{
puts("0");
continue;
}
for(int i=0; i<m; i++)
{
char x[12];
scanf("%s",x);
init(x,i);
}
getac();
for(int j=0; j<triecont; j++) for(int k=0; k<(1<<m); k++) dp[0][j][k]=0;
dp[0][0][0]=1;
for(int i=1; i<=n; i++)
{
for(int j=0; j<triecont; j++) for(int k=0; k<(1<<m); k++) dp[i%2][j][k]=0;
for(int j=0; j<triecont; j++)
{
for(int k=0; k<(1<<m); k++)
{
if(dp[1-i%2][j][k]==0) continue;
for(int l=0; l<26; l++)
{
trie *p=node[j]->next[l];
int tep=p->mark|k;
dp[i%2][p->id][tep]+=dp[1-i%2][j][k];
if(dp[i%2][p->id][tep]>=mod) dp[i%2][j][tep]%=mod;
}
}
}
}
__int64 ans=0;
for(int i=0; i<triecont; i++)
{
for(int j=0; j<(1<<m); j++)
{
if(judge(j)>=num)
{
ans+=dp[n%2][i][j];
if(ans>=mod) ans%=mod;
}
}
}
printf("%I64d\n",ans%mod);
}
return 0;
}

[AC自己主动机+状压dp] hdu 2825 Wireless Password的更多相关文章

  1. 【AC自动机】【状压dp】hdu2825 Wireless Password

    f(i,j,S)表示当前字符串总长度为i,dp到AC自动机第j个结点,单词集合为S时的方案数. 要注意有点卡常数,注意代码里的注释. #include<cstdio> #include&l ...

  2. poj 1699 Best Sequence(AC自己主动机+如压力DP)

    id=1699" target="_blank" style="">题目链接:poj 1699 Best Sequence 题目大意:给定N个D ...

  3. hdu 4057 AC自己主动机+状态压缩dp

    http://acm.hdu.edu.cn/showproblem.php?pid=4057 Problem Description Dr. X is a biologist, who likes r ...

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

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

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

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

  6. ACM-ICPC2018南京网络赛 AC Challenge(一维状压dp)

    AC Challenge 30.04% 1000ms 128536K   Dlsj is competing in a contest with n (0 < n \le 20)n(0<n ...

  7. hdu3247Resource Archiver (AC自动机+最短路+状压dp)

    Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 100000/100000 K (Java/Others) Total Submis ...

  8. HDU2825 Wireless Password 【AC自动机】【状压DP】

    HDU2825 Wireless Password Problem Description Liyuan lives in a old apartment. One day, he suddenly ...

  9. HDU 2825 Wireless Password(AC自动机 + 状压DP)题解

    题意:m个密码串,问你长度为n的至少含有k个不同密码串的密码有几个 思路:状压一下,在build的时候处理fail的时候要用 | 把所有的后缀都加上. 代码: #include<cmath> ...

随机推荐

  1. Git -- 自己项目关联新建的git

  2. 腾讯云会话服务器node+nginx

    1.除了一个正常的服务器还需要一个会话服务器(websocket),利用node加socket.io来做 2.正常安装Nginx yum install nginx 3.Nginx的配置内容略微不同( ...

  3. javascript函数,构造函数。js对象和json的区别。js中this指向问题

    函数是由事件驱动的或者当它被调用时执行的可重复使用的代码块.好处:在出现大量程序相同的时候,可以封装为一个function,这样只用调用一次,就能执行很多语句.(1)语法:函数就是包裹在花括号中的代码 ...

  4. Oracle API Gateway SOAP到REST协议转换

    1.SOAP到REST协议转换 打开policystudio,加入一个policy Container. 搜索extract rest 设置成为start 搜索set message,将url中的变量 ...

  5. verynginx +nginx_upstream_check_module模块,负载均衡检查模块。

    yum -y install git yum -y install patch yum -y install pcre-devel yum install -y zlib-devel   mkdir ...

  6. Codeforces D. Giving Awards 412 题解

    就是依照一定顺序输出排序. 比方a欠b的钱就不能先输出a然后输出b. 本题的技巧就是.要求的是不能先输出a然后输出b,可是能够先输出b然后输出a. 故此能够依照a欠b的钱的关系.建立图,然后DFS深度 ...

  7. ELK学习笔记

    一.elk框架和java1.8环境搭建 1.1: 环境说明 约定: centos6 iptables关闭 如果不关闭的话,需要开放对应的端口访问 selinux关闭 1.2: ELK简介 els:El ...

  8. [转]SQL Server 性能调优(cpu)

      研究cpu压力工具 perfom SQL跟踪 性能视图 cpu相关的wait event Signal wait time SOS_SCHEDULER_YIELD等待 CXPACKET等待 CME ...

  9. HDU 5094 --Maze【BFS &amp;&amp; 状态压缩】

    Maze Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 100000/100000 K (Java/Others) Total Sub ...

  10. libevent2源码分析之一:前言

    event的本质 libevent2中的event的本质是什么?只要是非同步阻塞的运行方式,肯定遵循事件的订阅-发布模型.通过event_new的函数原型可以理解,一个event即代表一次订阅,建立起 ...