HDU 2825 AC自动机+状压DP
2017-08-10 18:27
375 查看
题意
给M个字符串,要求组成一个长度为N的字符串,至少包含K个给定字符串。题解
利用AC自动机,我们可以进行状态转移, 以及模板匹配。要求目标串长度为N,且包含K个给定字符串。所以可以在包含给定字符串的AC自动机上进行状态转移。dp[i+1][u][last[u]|s]=(dp[i+1][u][last[u]|s]+dp[i][j][s])%MOD;
dp[i][j][k]表示,第i步,在j节点,已经包含的字符串状态为k。针对每一个在条件范围内的i,j,k都可以进行状态转移。最后统计一下i==n时包含字符串状态对应的字符串个数大于K的状态之和即为所求。
代码
#include <iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<vector> #include<cmath> #include<queue> #include<string> #include<set> #include<map> #include<bitset> #include<stack> #define UP(i,l,h) for(int i=l;i<h;i++) #define DOWN(i,h,l) for(int i=h-1;i>=l;i--) #define W(a) while(a) #define MEM(a,b) memset(a,b,sizeof(a)) #define INF 0x3f3f3f3f3f3f3f3f #define LL long long #define ULL unsigned long long #define MAXN 10000 #define EPS 1e-10 #define MOD 20090717 #define N 26 using namespace std; int n,m,k; int ch[110][26]; char st[15]; int sz,num; int val[110],hasnum[1050],f[110],last[110]; int dp[30][110][1050]; void insert() { int len=strlen(st); int u=0; UP(i,0,len) { int x=st[i]-'a'; if(!ch[u][x]) { val[sz]=0; ch[u][x]=sz++; } u=ch[u][x]; } val[u]=1<<num; } void cal() { UP(i,0,1<<10) { int j=i; W(j) { if(j%2==1) hasnum[i]++; j/=2; } } } void getFail() { MEM(f,0); MEM(last,0); queue<int> q; UP(i,0,26) { if(ch[0][i]) { q.push(ch[0][i]); last[ch[0][i]]=val[ch[0][i]]; } } W(!q.empty()) { int r=q.front(); q.pop(); UP(i,0,26) { int u=ch[r][i]; if(!u) { ch[r][i]=ch[f[r]][i]; continue; } q.push(u); int v=f[r]; f[u]=ch[v][i]; // cout<<val[u]<<endl; last[u]=(last[f[u]]|val[u]); } } } int main() { cal(); W(~scanf("%d%d%d",&n,&m,&k)) { if(n+m+k==0) break; MEM(val,0); MEM(ch,0); MEM(dp,0); sz=1; num=0; UP(i,0,m) { scanf("%s",st); insert(); num++; } getFail(); dp[0][0][0]=1; UP(i,0,n) { UP(j,0,sz) { UP(s,0,1<<m) { if(dp[i][j][s]==0) continue; UP(k,0,26) { int u=ch[j][k]; dp[i+1][u][last[u]|s]=(dp[i+1][u][last[u]|s]+dp[i][j][s])%MOD; } } } } int ans=0; UP(i,0,sz) { UP(j,0,1<<m) { if(hasnum[j]>=k) { ans=(ans+dp [i][j])%MOD; } } } printf("%d\n",ans); } } /* 2 2 1 abc bcd 1 1 1 a */
相关文章推荐
- HDU-2825 Wireless Password(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
- hdu 2825 Wireless Password (ac自动机+状压dp)
- hdu 2825 AC自动机+状压dp
- HDU 2825(Wireless Password-AC自动机+状压dp)
- 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 Wireless Password(AC自动机+状压DP)
- HDU 2825 Wireless Password(AC自动机+状态压缩DP)
- HDU 4758 Walk Through Squares && AC自动机+状压DP
- hdu 3341 Lost's revenge (ac自动机+状压dp)
- HDU 4057 AC自动机+状压dp
- HDU - 2825(AC自动机+状态压缩DP(需要优化))
- hdu 4057 Rescue the Rabbit(AC自动机+状压dp)
- hdu 2825(ac自动机+状态压缩dp)