HDU 4057 AC自动机+状态压缩DP
ZOJ 3545也是这个题。
每个节点的flag表示经过状态压缩的当前节点包含的所有字串。
在build的时候直接通过 flag = flag or fail->flag 来更新
f[i][j][k]表示长度为i时位于第j个节点包含字串状态为k是否可能
因为空间限制,利用滚动数组,注意初始化问题
转移的时候 if (f[i][j][k]) f[i+1][son][k|son->flag] =true;
初始化 f[0][0][0]=true 后顺推即可。
对于每一个状态,预处理出该状态的值。
见 void prework(); 函数
H[i] = H[i-lowbit(i)]+H[lowbit(i)];
最后对所有可达状态取最大值即可。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <iostream> #include <cstdio> #include <cstring> #include <queue> using namespace std; #define rep(i,a,b) for(int i=a;i<b;i++) const int MAXC = 4; const int MAXN = 1010; inline int lx(char c){ if (c=='A') return 0; if (c=='T') return 1; if (c=='C') return 2; return 3; } struct Tnode{ Tnode *ch[MAXC]; Tnode *f; int flag; void reset(){ memset(ch,0,sizeof(ch)); f = NULL; flag =0; } } *init; Tnode pool[MAXN]; int cnt; void insert(char *s,int qq){ Tnode *now = init; while(*s){ int p = lx(*s++); if (!now->ch[p]){ now->ch[p]=&pool[++cnt]; pool[cnt].reset(); } now = now->ch[p]; } now->flag=now->flag|qq; } queue <Tnode*> q; void build(){ q.push(init); while(!q.empty()){ Tnode *now = q.front(); q.pop(); rep(i,0,MAXC){ if (now->ch[i]){ Tnode *p=now->f; while(p && !p->ch[i]) p=p->f; now->ch[i]->f = p?p->ch[i]:init; q.push(now->ch[i]); } } } init->f=init; rep(i,0,MAXC) if (init->ch[i]) q.push(init->ch[i]); else init->ch[i]=init; while(!q.empty()){ Tnode *now = q.front(); now->flag = now->flag | now->f->flag; q.pop(); rep(i,0,MAXC) if (now->ch[i]) q.push(now->ch[i]); else now->ch[i]=now->f->ch[i]; } } int Q[15]; bool f[2][MAXN][1024]; int N,L; char s[110]; bool ans[1024]; int H[1024]; void dp(){ memset(ans,0,sizeof(ans)); int p1=0; int p2=1; memset(f[p1],0,sizeof(f[p1])); f[0][0][0]=true; rep(l,0,L){ memset(f[p2],0,sizeof(f[p2])); rep(i,0,cnt+1){ rep(k,0,1<<N){ if (!f[p1][i][k]) continue; rep(c,0,MAXC){ f[p2][pool[i].ch[c]-pool][k|pool[i].ch[c]->flag]=true; } } } swap(p1,p2); } rep(i,0,cnt+1) rep(j,0,1<<N) if (f[p1][i][j]) ans[j]=true; } inline int lowbit(int p){ return p&-p; } void prework(){ memset(H,0,sizeof(H)); H[0]=0; rep(i,0,N) H[1<<i]=Q[i]; rep(i,1,1<<N) H[i]=H[i-lowbit(i)]+H[lowbit(i)]; } int main(){ freopen("in.txt","r",stdin); while(scanf("%d%d\n",&N,&L)!=EOF){ init = &pool[0]; cnt=0; pool[0].reset(); rep(i,0,N){ scanf("%s",s); scanf("%d\n",&Q[i]); insert(s,1<<i); } build(); prework(); dp(); int rul = -1; rep(i,0,1<<N) if (ans[i]) rul = max(rul,H[i]); if (rul<0) printf("No Rabbit after 2012!\n"); else printf("%d\n",rul); } }