HDU2825 Wireless Password AC自动机+状压DP
来源:互联网 发布:公司网络管理需求分析 编辑:程序博客网 时间:2024/05/14 23:32
题意:
给出密码的长度n,可能含有密码字串的个数m和密码至少含有密码字串的个数k,求有多少种情况。
分析:
因为这个题不是问的密码字串必须全部包含,所以不能矩阵加速= =
果然n的大小变得很小只有25
可以用状压DP来做,具体是每个AC自动机内的节点都编个号,然后getfail的时候像以前矩阵加速getfail一样,假设当前节点的编号是2^k,当前节点的fail指向的点的编号是2^j,那么就把当前节点的编号更新成2^k+2^j(以前矩阵加速是fail节点不能选当前节点也不能选)。
然后dp[i][j][k]
表示走到密码的第i位,在AC自动机上匹配到第j个点,状态为k的方案数。 dp[i][j][k]
就可以推向dp[i+1][jj][k|cnt[jj]]
(cnt数组存放节点编号)。
竟然1A了,爽啊。
#include<iostream>#include<cstdio>#include<cstring>#include<queue>using namespace std;int a,b,c,mod=20090717;char s[30];struct ACautomata{ int next[255][26],fail[255],cnt[255],dp[26][255][1<<10],bitcnt[1<<10],num,root; int newnode() { memset(next[num],0,sizeof next[num]); cnt[num]=0; return num++; } void init() { num=0; root=newnode(); bitcnt[0]=0; for(int i=1;i<(1<<10);++i) bitcnt[i]=bitcnt[i>>1]+(i&1); } void insert(char *s,int l) { int len=strlen(s),cur=root; for(int i=0;i<len;++i) { int &tmp=next[cur][s[i]-'a']; if(!tmp)tmp=newnode(); cur=tmp; } cnt[cur]=l; } void getfail() { queue<int>q; fail[root]=root; for(int i=0;i<26;++i) { int u=next[root][i]; if(u) { fail[u]=0; q.push(u); } else next[root][i]=0; } while(!q.empty()) { int cur=q.front(); q.pop(); for(int i=0;i<26;++i) { int u=next[cur][i]; if(u) { fail[u]=next[fail[cur]][i]; cnt[u]|=cnt[fail[u]]; q.push(u); } else next[cur][i]=next[fail[cur]][i]; } } } int work(int n,int m,int k) { for(int i=0;i<=n;++i) for(int j=0;j<num;++j) for(int p=0;p<(1<<m);++p) dp[i][j][p]=0; dp[0][0][0]=1; for(int i=0;i<n;++i) for(int j=0;j<num;++j) for(int p=0;p<(1<<m);++p) { if(dp[i][j][p]==0)continue; for(int l=0;l<26;++l) { int u=next[j][l]; (dp[i+1][u][p|cnt[u]]+=dp[i][j][p])%=mod; } } int res=0; for(int i=0;i<num;++i) for(int j=0;j<(1<<m);++j) if(bitcnt[j]>=k)(res+=dp[n][i][j])%=mod; return res; }}ac;int main(){ while(~scanf("%d%d%d",&a,&b,&c)&&(a+b+c)) { ac.init(); for(int i=0;i<b;++i) scanf("%s",s),ac.insert(s,1<<i); ac.getfail(); printf("%d\n",ac.work(a,b,c)); }}
0 0
- hdu2825 Wireless Password AC自动机+状压DP
- hdu2825---Wireless Password(AC自动机+状压dp)
- hdu2825 Wireless Password [AC自动机+状压dp]
- AC自动机+状压dp hdu2825 Wireless Password
- HDU2825 Wireless Password AC自动机+状压DP
- 【HDU2825】Wireless Password【AC自动机】【状压DP】
- hdu2825 Wireless Password(AC自动机+状压dp)
- hdu2825 Wireless Password(AC自动机+状压dp)
- HDU2825 Wireless Password AC自动机
- HDU2825 Wireless Password【AC自动机】
- [HDU2825]Wireless Password-AC自动机
- HDU2825 Wireless Password AC自动机+状态压缩DP
- 【HDU2825】Wireless Password,AC自动机+状态压缩DP
- hdu2825-(AC自动机+状压DP)
- HDU 2825 Wireless Password(AC自动机+状压DP)
- HDU 2825 Wireless Password && AC自动机+状压DP
- hdu 2825 Wireless Password(AC自动机+状压DP)
- [AC自动机+状压dp] hdu 2825 Wireless Password
- Jmeter-java请求执行报错:java.lang.NoSuchFieldError: INSTANCE
- 经典算法设计:动态规划(2)字符串匹配
- 利用gdb定位段错误(Segmentation fault)
- 单源最短路径问题之Dijkstra算法详解
- 函数指针数组
- HDU2825 Wireless Password AC自动机+状压DP
- Java web开发编码设置
- Ubuntu下Oracle JDK的一般安装及环境配置
- Java Swing:Nim游戏实现
- Android studio 如何导入Eclipse项目
- Weblogic内存回收机制设计不合理导致服务器CPU使用率100%
- ios控制器的生命周期
- linux:vim-abolish 的安装和使用
- Django