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的主要内容,如果未能解决你的问题,请参考以下文章

A题 AC自动机+状压dp

AC自动机+状压DP

BZOJ 1559: [JSOI2009]密码( AC自动机 + 状压dp )

HDU2825 Wireless Password(AC自动机+状压DP)

计蒜客 30994 - AC Challenge - [状压DP][2018ICPC南京网络预赛E题]

做题记录