A题 AC自动机+状压dp
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了A题 AC自动机+状压dp相关的知识,希望对你有一定的参考价值。
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<queue> 5 #define inf 102333 6 #define rep(i,j,k) for(register int i = j; i <= k; i++) 7 #define low(i,j,k) for(register int i = j; i <= k; i++) 8 #define maxn 105 9 using namespace std; 10 11 inline int read(){ 12 int s = 0, t = 1; char c = getchar(); 13 while( !isdigit(c) ) { if( c == ‘-‘ ) t = -1; c = getchar(); } 14 while( isdigit(c) ) s = s * 10 + c - 48, c = getchar(); 15 return s * t; 16 } 17 18 int ch[maxn*20][4], f[maxn*20], last[maxn*20], val[maxn*20], n, l; 19 int dp[2][1024][1023], key[12], value[523]; 20 char c[105]; 21 22 int idx(char c) { if( c == ‘A‘ ) return 0; if( c == ‘T‘ ) return 1; if( c == ‘C‘ ) return 2; if( c == ‘G‘ ) return 3; } 23 24 int sz; 25 void clear() { sz = 0; val[sz] = 0; f[sz] = 0, last[sz] = 0; memset(ch[0],0,sizeof(ch[0])); memset(dp,0,sizeof(dp)); } 26 void insert(char *c, int now){ 27 int s = strlen(c), p = 0; 28 rep(i,0,s-1){ 29 int t = idx(c[i]); if( !ch[p][t] ) { ch[p][t] = ++sz; memset(ch[sz],0,sizeof(ch[sz])); val[sz] = 0; f[sz] = 0, last[sz] = 0; } 30 p = ch[p][t]; 31 } 32 val[p] |= now; 33 } 34 35 void get_fail() { 36 queue<int> q; 37 rep(i,0,3) { int u = ch[0][i]; if( u ) q.push(u); } 38 while( !q.empty() ){ 39 int r = q.front(); q.pop(); 40 rep(i,0,3){ 41 int u = ch[r][i]; if( !u ) { ch[r][i] = ch[f[r]][i]; continue; } q.push(u); 42 int v = f[r]; while( v && !ch[v][i] ) v = f[v]; f[u] = ch[v][i]; 43 last[u] = val[f[u]] ? f[u] : last[f[u]]; val[u] |= val[last[u]]; 44 } 45 } 46 } 47 48 inline int getkey(int b){ 49 int ret = 0; 50 rep(i,1,n) if( b & key[i] ) ret += value[key[i]]; 51 return ret; 52 } 53 54 int main() { 55 key[1] = 1; rep(i,2,11) key[i] = key[i-1] * 2; 56 while( scanf("%d %d", &n,&l) == 2 ) { 57 clear(); 58 rep(i,1,n) { scanf("%s", c); value[key[i]] = read(); insert(c,key[i]); } get_fail(); 59 //rep(i,0,sz) cout<<i<<" "<<val[i]<<" "<<f[i]<<endl; cout<<endl; 60 int now = 0, pre = 1; dp[now][0][0] = 1; 61 rep(i,0,l-1){ 62 swap(now,pre); 63 rep(j,0,key[n+1]-1) 64 rep(k,0,sz){ 65 if( !dp[pre][j][k] ) continue; //cout<<i<<" "<<j<<" "<<k<<" "<<getkey(j)<<endl; 66 rep(l,0,3){ int to = j | val[ch[k][l]]; dp[now][to][ch[k][l]] = 1; }//cout<<i+1<<" "<<to<<" "<<ch[k][l]<<" "<<getkey(to)<<endl; } 67 dp[pre][j][k] = 0; 68 } 69 } 70 int ans = -1; 71 rep(j,0,key[n+1]-1){ 72 if( ans >= getkey(j) ) continue; 73 rep(k,0,sz){ 74 if( !dp[now][j][k] ) continue; 75 ans = max(ans,getkey(j)); break; 76 } 77 } 78 if( ans >= 0 ) printf("%d\n", ans); 79 else printf("No Rabbit after 2012!\n"); 80 } 81 return 0; 82 }
以上是关于A题 AC自动机+状压dp的主要内容,如果未能解决你的问题,请参考以下文章
BZOJ 1559: [JSOI2009]密码( AC自动机 + 状压dp )
HDU2825 Wireless Password(AC自动机+状压DP)