[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> ...
随机推荐
- [Java基础] Java多线程-工具篇-BlockingQueue
转载自: http://www.cnblogs.com/jackyuj/archive/2010/11/24/1886553.html 前言: 在新增的Concurrent包中,BlockingQue ...
- 大数据的开始:安装hadoop
为实现全栈,从今天开始研究Hadoop,个人体会是成为某方面的专家需要从三个方面着手 系统化的知识(需要看书或者比较系统的培训) 碎片化的知识(需要根据关注点具体的深入的了解) 经验的积累(需要遇到问 ...
- python中list/tuple/dict/set的区别
序列是Python中最基本的数据结构.序列中的每个元素都分配一个数字 - 它的位置,或索引,第一个索引是0,第二个索引是1,依此类推.Python有6个序列的内置类型,但最常见的是列表list和元组t ...
- Python扫描指定文件夹下(包含子文件夹)的文件
扫描指定文件夹下的文件.或者匹配指定后缀和前缀的函数. 假设要扫描指定文件夹下的文件,包含子文件夹,调用scan_files("/export/home/test/") 假设要扫描 ...
- javascript快速入门5--数组与对象
数组 数组,实际上就是将一大堆相似的数据有秩序的放在格子箱中,十分像药房里的那些柜子. 数据1 数据2 数据3 数据4 数据5 数据6 用代码创建数组 var arr = new Array();// ...
- unity3d开发app的框架
unity3d开发app的框架,开源地址 https://coding.net/u/liuhaili/p/U3DApp/git 希望能和有相同兴趣的朋友一起完善 打开Scene下的MainUI场景 目 ...
- linux下javadoc生成文件出现中文乱码
javadoc命令的正确使用姿势 javadoc -d apidoc -windowtitle Testing -doctitle 'The API of javadoc' -header 'My c ...
- Vue 前端路由 vue-router
1.前端路由 后端路由:多页面,服务器端渲染好返回给浏览器. 前端路由:改变url不向服务器发送请求:前端可以监听url变化:前端可以解析url并执行相应操作. 前后端分离:后端只提供API来返回数据 ...
- 关于窗体跟随与 PointToScreen
今日写一段测试代码,实现的功能是,当一个输入框获得焦点时,某个帮助窗体跟随在其下方显示.代码很简单,本来没有什么值得一提的.但实验的时候发现,有些控件能较好地跟随,但有些不能,而且距离十分远. 主要代 ...
- UITabBarController超强拓展
代码地址如下:http://www.demodashi.com/demo/11901.html 一.运行效果图 二.项目结构截图 三.主要API 我们主要关注的是TLTabBarController, ...