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

题目链接:hdu_2825_Wireless Password

题意:

给你m个串,问长度为n至少含k个串的字符串有多少个

题解:

设dp[i][j][k]表示考虑到长度为i,第j个自动机的节点,含有k这个压缩状态的方案数,然后DP下去就行了

 1 #include<bits/stdc++.h>
 2 #define F(i,a,b) for(int i=a;i<=b;i++)
 3 using namespace std;
 4
 5 const int mod=20090717;
 6 const int AC_N=10*51,tyn=26;//数量乘串长,类型数
 7 struct AC_automation{
 8     int tr[AC_N][tyn],cnt[AC_N],Q[AC_N],fail[AC_N],tot;
 9     inline int getid(char x){return x-‘a‘;}
10     void nw(){cnt[++tot]=0,fail[tot]=0;memset(tr[tot],0,sizeof(tr[tot]));}
11     void init(){tot=-1,fail[0]=-1,nw();}
12     void insert(char *s,int ids,int x=0){
13         for(int len=strlen(s),i=0,w;i<len;x=tr[x][w],i++)
14             if(!tr[x][w=getid(s[i])])nw(),tr[x][w]=tot;
15         cnt[x]|=1<<ids;//串尾标记
16     }
17     void build(int head=1,int tail=0){
18         for(int i=0;i<tyn;i++)if(tr[0][i])Q[++tail]=tr[0][i];
19         while(head<=tail)for(int x=Q[head++],i=0;i<tyn;i++)
20             if(tr[x][i])fail[tr[x][i]]=tr[fail[x]][i],Q[++tail]=tr[x][i],cnt[tr[x][i]]|=cnt[tr[fail[x]][i]];
21             else tr[x][i]=tr[fail[x]][i];
22     }
23 }AC;
24
25 char s[111];
26 int dp[26][111][1<<11],n,m,k,ans;
27
28 inline int getans(int s,int an=0)
29 {
30     F(i,0,9)if((s>>i)&1)an++;
31     return an;
32 }
33
34 int main()
35 {
36     while(~scanf("%d%d%d",&n,&m,&k)&&(n||m||k))
37     {
38         AC.init(),ans=0;
39         F(i,0,m-1)scanf("%s",s),AC.insert(s,i);
40         AC.build();
41         memset(dp,0,sizeof(dp)),dp[0][0][0]=1;
42         F(i,0,n-1)F(j,0,AC.tot)for(int k=0;k<(1<<m);++k)
43         if(dp[i][j][k]!=0)F(ii,0,25)
44         {
45             int *p=&dp[i+1][AC.tr[j][ii]][k|AC.cnt[AC.tr[j][ii]]];
46             *p=(*p+dp[i][j][k])%mod;
47         }
48         F(i,0,AC.tot)for(int j=0;j<(1<<m);j++)if(getans(j)>=k)ans=(ans+dp[n][i][j])%mod;
49         printf("%d\n",ans);
50     }
51     return 0;
52 }

时间: 2024-08-25 09:24:10

hdu_2825_Wireless Password(AC自动机+状压DP)的相关文章

hdu 2825 Wireless Password(AC自动机+状压DP)

题目链接:hdu 2825 Wireless Password 题目大意:N,M,K,M个字符串作为关键码集合,现在要求长度为N,包含K个以上的关键码的字符串有多少个. 解题思路:AC自动机+dp,滚动数组,因为关键码个数不会超过10个,所以我们用二进制数表示匹配的状态.dp[i][j][k] 表示到第i个位置,j节点,匹配k个字符串. #include <cstdio> #include <cstring> #include <queue> #include <

hdu2825---Wireless Password(AC自动机+状压dp)

Wireless Password Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 4688 Accepted Submission(s): 1433 Problem Description Liyuan lives in a old apartment. One day, he suddenly found that there was a

hdu 2825 aC自动机+状压dp

Wireless Password Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 5640    Accepted Submission(s): 1785 Problem Description Liyuan lives in a old apartment. One day, he suddenly found that there

poj 1699 Best Sequence(AC自动机+状压DP)

题目链接:poj 1699 Best Sequence 题目大意:给定N个DNA序列,问说最少多长的字符串包含所有序列. 解题思路:AC自动机+状压DP,先对字符串构造AC自动机,然后在dp[s][i]表示匹配了s,移动到节点i时候的最短步数. #include <cstdio> #include <cstring> #include <queue> #include <vector> #include <iostream> #include &

【HDU3341】 Lost&#39;s revenge (AC自动机+状压DP)

Lost's revenge Time Limit: 5000MS Memory Limit: 65535KB 64bit IO Format: %I64d & %I64u Description Lost and AekdyCoin are friends. They always play "number game"(A boring game based on number theory) together. We all know that AekdyCoin is t

HDU 3341 Lost&#39;s revenge(AC自动机+状压DP)

Lost's revenge Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)Total Submission(s): 4548    Accepted Submission(s): 1274 Problem Description Lost and AekdyCoin are friends. They always play "number game"(A bor

[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的方案数 然后就是一个四重循

[AC自动机+状压dp] hdu 4534 郑厂长系列故事——新闻净化

题意:中文的题目,意思就是说有很多串,每个串都有权值,权值为999的串必须出现,-999的串必须不出现.权值在-999~999之间. 然后必须出现的串不超过8个.然后给一个全为小写目标串,问最少需要删除多少个字母才能够保证必须出现的串都出现,次数一样保证权值最大.输出次数和权值. 然后根据样例,那些必须出现的串,其实权值是0. 思路: 很明显一开始建自动机构成trie图,但是需要注意的就是mark和sum的更新.个人是把所有中间的节点的sum全部赋值成了-inf. 接着只有8个必须出现的串,所以

POJ1699 Best Sequence(AC自动机+状压DP)

题目,包含所有的给定的n个DNA片段的序列的最短长度. 裸的AC自动机上的DP题. dp[S][u]表示已经包含的DNA片段集合为S,且当前后缀状态是自动机第u个结点的最短长度 dp[0][0]=0 我为人人+队列轻松转移.. 1 #include<cstdio> 2 #include<cstring> 3 #include<queue> 4 #include<algorithm> 5 using namespace std; 6 #define INF (