hdu 2825 AC自动机+状压dp
2014-10-29 22:54
253 查看
假设一个字符串长为n,现在在j这个位置,此时已经包含了一个模式串集合(由于m只有10,所有可以用状压来表示模式串),到下一个位置时,一共有26种情况,现在你想知道的是多一个字母后会多几个模式串,由于是多匹配问题便想到了AC自动机,而此时只要纪录走道j这个位置时trie上走到k这个位置。所以状态便是dp[i][j][k]便是长度为i多串走道j这个trie节点同时含有k这个集合的模式串的个数。
#include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #include<queue> #include<vector> #define mod 20090717 using namespace std; char c[15][15]; int ch[105][26],tot;//从0到tot int val[105]; int to[105][26]; int fail[105]; vector<int> g[105]; int vv[105]; int dp[26][105][1025]; queue<int >q; void init(void){ memset(ch,0,sizeof(ch)); memset(val,0,sizeof(val)); memset(fail,0,sizeof(fail)); memset(vv,0,sizeof(vv)); memset(to,0,sizeof(to)); } void get_trie(int n){ int i,j,f,p; tot=0; for(i=0;i<n;i++){ p=(int)strlen(c[i]); f=0; for(j=0;j<p;j++){ if(ch[f][c[i][j]-'a']) f=ch[f][c[i][j]-'a']; else{ ch[f][c[i][j]-'a']=++tot; f=tot; } } val[f]=i+1; } } void get_fail(void){ int i,fa,p; for(i=0;i<26;i++){ if(ch[0][i]) q.push(ch[0][i]); } while(!q.empty()){ p=q.front(); q.pop(); fa=fail[p]; for(i=0;i<26;i++){ if(ch[p][i]){ q.push(ch[p][i]); fa=fail[p]; while(fa&&!ch[fa][i]) fa=fail[fa]; fa=ch[fa][i]; fail[ch[p][i]]=fa; } } } for(i=0;i<=tot;i++){ p=i; while(p){ if(val[p]) vv[i]|=(1<<(val[p]-1)); p=fail[p]; } } for(i=0;i<=tot;i++){ for(int j=0;j<26;j++){ p=i; while(p&&!ch[p][j]) p=fail[p]; p=ch[p][j]; to[i][j]=p; } } } int get(int x){ int s=0; while(x>0){ if(x&1) s++; x=x>>1; } return s; } int solve(int n,int m,int k){ int i,j,p,f,x; p=1<<n; for(i=0;i<=m;i++){ for(j=0;j<=tot;j++){ for(f=0;f<p;f++) dp[i][j][f]=0; } } dp[0][0][0]=1; for(i=0;i<m;i++){ for(j=0;j<=tot;j++){ for(f=0;f<p;f++){ if(dp[i][j][f]==0) continue; for(int v=0;v<26;v++){ dp[i+1][to[j][v]][vv[to[j][v]]|f]+=dp[i][j][f]; dp[i+1][to[j][v]][vv[to[j][v]]|f]%=mod; } } } } int s=0; for(i=0;i<=tot;i++){ for(j=0;j<p;j++){ x=get(j); if(x>=k) s+=dp[m][i][j]; s%=mod; } } return s; }int main() { int i,n,m,k; while(1){ scanf("%d%d%d",&m,&n,&k); if(m==0&&n==0&&k==0) break; init(); for(i=0;i<n;i++) scanf("%s",c[i]); get_trie(n); get_fail(); printf("%d\n",solve(n,m,k)); } }
相关文章推荐
- hdu 2825 AC自动机+状压dp
- hdu 2825(ac自动机+状态压缩dp)
- [HDU 2825] Wireless Password (AC自动机+状态压缩DP)
- HDU 2825 Wireless Password(AC自动机+状压DP)
- hdu 2825 Wireless Password(AC自动机+压缩DP,5级)
- HDU - 2825 Wireless Password(AC自动机+DP)
- H - Wireless Password HDU - 2825(AC自动机+状压DP)
- hdu 2825(ac自动机+状态压缩dp)
- HDU 2825 Wireless Password(AC自动机+状压DP)
- HDU - 2825(AC自动机+状态压缩DP(需要优化))
- HDU 2825 AC自动机+状压DP
- HDU 2825 Wireless Password && AC自动机+状压DP
- HDU 2825 Wireless Password(AC自动机+状态压缩DP)
- hdu 2825 Wireless Password(AC自动机+状压DP)
- HDU 2825(Wireless Password-AC自动机+状压dp)
- hdu 2825 Wireless Password (ac自动机+状压dp)
- hdu 2825 Wireless Password(AC自动机+压缩DP,5级)
- HDU-2825 Wireless Password(AC自动机+状压DP)
- hdu 2825 aC自动机+状压dp
- hdu 2825 Wireless Password (ac自动机+状态压缩dp)