HDU4057 Rescue the Rabbit(AC自动机+状压DP)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU4057 Rescue the Rabbit(AC自动机+状压DP)相关的知识,希望对你有一定的参考价值。

题目大概是给几个DNA片段以及它们各自的权值,如果一个DNA包含某个片段那么它的价值就加上这个片段的权值,同时包含多个相同DNA片段也只加一次,问长度l的DNA可能的最大价值。

HDU2825大同小异。

  • dp[i][j][S]表示长度i(自动机转移i步)、后缀状态为自动机第j个结点、包含的DNA片段为集合S 的DNA最大价值
  • dp[0][0][0]=0
  • 我为人人转移,从dp[i][j][S]向ATCG四个方向更新dp[i+1][j‘][S‘]
  1. 注意的是要用滚动数组,不然要开上百兆数组。
  2. 用滚动数组要注意初始化。
  3. 转移过程有些计算可以预处理出来,存在数组里,虽然不预处理应该也不会TLE,题目时间给了10000ms。
 1 #include<cstdio>
 2 #include<cstring>
 3 #include<queue>
 4 using namespace std;
 5 #define INF (1<<30)
 6 int tn,ch[1111][4],fail[1111],flag[1111];
 7 int idx[128];
 8 void insert(char *s,int k){
 9     int x=0;
10     for(int i=0; s[i]; ++i){
11         int y=idx[s[i]];
12         if(ch[x][y]==0) ch[x][y]=++tn;
13         x=ch[x][y];
14     }
15     flag[x]|=1<<k;
16 }
17 void init(){
18     memset(fail,0,sizeof(fail));
19     queue<int> que;
20     for(int i=0; i<4; ++i){
21         if(ch[0][i]) que.push(ch[0][i]);
22     }
23     while(!que.empty()){
24         int x=que.front(); que.pop();
25         for(int i=0; i<4; ++i){
26             if(ch[x][i]) que.push(ch[x][i]),fail[ch[x][i]]=ch[fail[x]][i];
27             else ch[x][i]=ch[fail[x]][i];
28             flag[ch[x][i]]|=flag[ch[fail[x]][i]];
29         }
30     }
31 }
32 int d[2][1111][1<<10],VAL[1<<10];
33 int main(){
34     idx[A]=0; idx[G]=1; idx[T]=2; idx[C]=3;
35     int m,n,a;
36     char str[111];
37     int val[11];
38     while(~scanf("%d%d",&m,&n)){
39         tn=0;
40         memset(ch,0,sizeof(ch));
41         memset(flag,0,sizeof(flag));
42         for(int i=0; i<m; ++i){
43             scanf("%s%d",str,val+i);
44             if(strlen(str)>100) continue;
45             insert(str,i);
46         }
47         for(int i=1; i<(1<<m); ++i){
48             for(int j=0; j<m; ++j){
49                 if((i>>j)&1) VAL[i]=VAL[i^(1<<j)]+val[j];
50             }
51         }
52         init();
53         for(int j=0; j<=tn; ++j){
54             for(int k=0; k<(1<<m); ++k) d[0][j][k]=-INF;
55         }
56         d[0][0][0]=0;
57         for(int i=0; i<n; ++i){
58             int x=i&1;
59             for(int j=0; j<=tn; ++j){
60                 for(int k=0; k<(1<<m); ++k) d[x^1][j][k]=-INF;
61             }
62             for(int j=0; j<=tn; ++j){
63                 for(int k=0; k<(1<<m); ++k){
64                     if(d[x][j][k]==-INF) continue;
65                     for(int y=0; y<4; ++y){
66                         d[x^1][ch[j][y]][k|flag[ch[j][y]]]=max(d[x^1][ch[j][y]][k|flag[ch[j][y]]],d[x][j][k]+VAL[k^(k|flag[ch[j][y]])]);
67                     }
68                 }
69             }
70         }
71         int res=-INF;
72         for(int i=0; i<=tn; ++i){
73             for(int j=0; j<(1<<m); ++j) res=max(res,d[n&1][i][j]);
74         }
75         if(res<0) puts("No Rabbit after 2012!");
76         else printf("%d\\n",res);
77     }
78     return 0;
79 } 

 

以上是关于HDU4057 Rescue the Rabbit(AC自动机+状压DP)的主要内容,如果未能解决你的问题,请参考以下文章

hdu Rescue (bfs)

HDU1242 Rescue

HDU 1242 Rescue

HDU 1242 Rescue

hdu 1242 Rescue

HDU - 1242 Rescue