[AC自己主动机+状压dp] hdu 2825 Wireless Password
题意:
给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的更多相关文章
- 【AC自动机】【状压dp】hdu2825 Wireless Password
f(i,j,S)表示当前字符串总长度为i,dp到AC自动机第j个结点,单词集合为S时的方案数. 要注意有点卡常数,注意代码里的注释. #include<cstdio> #include&l ...
- poj 1699 Best Sequence(AC自己主动机+如压力DP)
id=1699" target="_blank" style="">题目链接:poj 1699 Best Sequence 题目大意:给定N个D ...
- hdu 4057 AC自己主动机+状态压缩dp
http://acm.hdu.edu.cn/showproblem.php?pid=4057 Problem Description Dr. X is a biologist, who likes r ...
- HDU 2825 Wireless Password (AC自己主动机,DP)
pid=2825">http://acm.hdu.edu.cn/showproblem.php? pid=2825 Wireless Password Time Limit: 2000 ...
- HDU - 2825 Wireless Password(AC自己主动机+DP)
Description Liyuan lives in a old apartment. One day, he suddenly found that there was a wireless ne ...
- 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 ...
- hdu3247Resource Archiver (AC自动机+最短路+状压dp)
Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 100000/100000 K (Java/Others) Total Submis ...
- HDU2825 Wireless Password 【AC自动机】【状压DP】
HDU2825 Wireless Password Problem Description Liyuan lives in a old apartment. One day, he suddenly ...
- HDU 2825 Wireless Password(AC自动机 + 状压DP)题解
题意:m个密码串,问你长度为n的至少含有k个不同密码串的密码有几个 思路:状压一下,在build的时候处理fail的时候要用 | 把所有的后缀都加上. 代码: #include<cmath> ...
随机推荐
- tengine + lua 实现流量拷贝
环境搭建参考地址:http://www.cnblogs.com/cp-miao/p/7505910.html cp.lua local res1, res2, action action = ngx. ...
- linux使用其它用户 su - op -c
su - op -c "whoami"
- git rebase、git merge、git cherry-pick 使用详解
1.git cherry-pick 是合入其他分支的某一次或者几次提交(cherry-pick是挑选的意思):把其他分支的某些功能合入当前分支 2.git merge 把其他分支合入当前分支,一般用作 ...
- Druid对比Vertica
怎么比较Druid和Vertica? Vertica 类似与之前介绍的ParAccel/Redshift(Druid-vs-Redshift). 不是实时注入数据: 提供SQL的全部语法支持 另外一个 ...
- MapReduce初学习
内容来源,工具下载:点此链接 点此链接 Mapreduce概述: MapReduce是一种分布式计算模型,主要用于搜索领域,解决海量数据的计算问题.MR是由两个阶段组成,Map和Reduce,用户只 ...
- 解决Linux关闭终端(关闭SSH等)后运行的程序或者服务自动停止【后台运行程序】
问题描述:当SSH远程连接到服务器上,然后运行一个服务 ./catalina.sh start,然后把终端开闭(切断SSH连接)之后,发现该服务中断,导致网页无法访问. 解决方法:使用nohup命 ...
- 深入浅出 消息队列 ActiveMQ (转)
启动成功就可以访问管理员界面:http://localhost:8161/admin,默认用户名和密码admin/admin.如果你想修改用户名和密码的话,在conf/jetty-realm.prop ...
- Idea 代码编辑错误不飘红提示
Power Save Mode 勾选去掉即可
- 除了cPickle,cjson外还有没有更高效点的序列化库了
除了cPickle,cjson外还有没有更高效点的序列化库了 http://blog.csdn.net/chen_lovelotus/article/details/7228745 msgpack最快 ...
- MPTCP 源码分析(三) 子路径选择
简述: 支持MPTCP的链路中存在多条子路径,因此在发送数据的时候需要选择最优路径来进行操作. MPTCP利用内核通知链对MPTCP中各子路径进行增加路径.删除路径.修改路径优先级的操作.M ...