zoj3545Rescue the Rabbit (AC自动机+状压dp+滚动数组)
来源:互联网 发布:通达信公式源码 编辑:程序博客网 时间:2024/05/16 13:47
Dr. X is a biologist, who likes rabbits very much and can do everything for them. 2012 is coming, and Dr. X wants to take some rabbits to Noah's Ark, or there are no rabbits any more.
A rabbit's genes can be expressed as a string whose length is l (1 ≤ l ≤ 100) containing only 'A', 'G', 'T', 'C'. There is no doubt that Dr. X had a in-depth research on the rabbits' genes. He found that if a rabbit gene contained a particular gene segment, we could consider it as a good rabbit, or sometimes a bad rabbit. And we use a value W to measure this index.
We can make a example, if a rabbit has gene segment "ATG", its W would plus 4; and if has gene segment "TGC", its W plus -3. So if a rabbit's gene string is "ATGC", its W is 1 due to ATGC contains both "ATG"(+4) and "TGC"(-3). And if another rabbit's gene string is "ATGATG", its W is 4 due to one gene segment can be calculate only once.
Because there are enough rabbits on Earth before 2012, so we can assume we can get any genes with different structure. Now Dr. X want to find a rabbit whose gene has highestW value. There are so many different genes with length l, and Dr. X is not good at programming, can you help him to figure out the W value of the best rabbit.
Input
There are multiple test cases. For each case the first line is two integers n (1 ≤ n ≤ 10),l (1 ≤ l ≤ 100), indicating the number of the particular gene segment and the length of rabbits' genes.
The next n lines each line contains a string DNAi and an integer wi (|wi| ≤ 100), indicating this gene segment and the value it can contribute to a rabbit's W.
Output
For each test case, output an integer indicating the W value of the best rabbit. If we found this value is negative, you should output "No Rabbit after 2012!".
Sample Input
2 4ATG 4TGC -31 6TGC 44 1A -1T -2G -3C -4
Sample Output
44No Rabbit after 2012!
Hint
case 1:we can find a rabbit whose gene string is ATGG(4), or ATGA(4) etc.
case 2:we can find a rabbit whose gene string is TGCTGC(4), or TGCCCC(4) etc.
case 3:any gene string whose length is 1 has a negative W.
题意:给你n个模板串,每一个模板串对应一个数值,有正也有负,然你构造一个长度为m的模板串,使得模板串的价值最大,且一种模板串如果重复出现只统计一次。
思路:考虑到n<=10,所以用状压dp的思想,设状态为dp[i][j][state]表示走了i步,当前节点为j,含有的单词状态为state的最大值。但是这个状态消耗的内存太大,有100*1000*1024,所以用滚动数组(这点是看了别人的题解才发现的,果然意识不够啊..= .=),然后构造trie图,dp就行了。
#include<iostream>#include<stdio.h>#include<stdlib.h>#include<string.h>#include<math.h>#include<vector>#include<map>#include<set>#include<queue>#include<stack>#include<string>#include<algorithm>using namespace std;typedef long long ll;#define inf 99999999#define pi acos(-1.0)#define maxnode 1100int t0,t1,t2,t3;char s[14],str[50];int cas=0;int dp[2][1005][1030],w[1030];int n,m;struct trie{ int sz,root,val[maxnode],next[maxnode][4],fail[maxnode]; int q[1111111]; void init(){ int i; sz=root=0; val[0]=0; for(i=0;i<4;i++){ next[root][i]=-1; } } int idx(char c){ if(c=='A')return 0; if(c=='C')return 1; if(c=='T')return 2; if(c=='G')return 3; } void charu(char *s,int index){ int i,j,u=0; int len=strlen(s); for(i=0;i<len;i++){ int c=idx(s[i]); if(next[u][c]==-1){ sz++; val[sz]=0; next[u][c]=sz; u=next[u][c]; for(j=0;j<4;j++){ next[u][j]=-1; } } else{ u=next[u][c]; } } val[u]|=(1<<index-1); } void build(){ int i,j; int front,rear; front=1;rear=0; for(i=0;i<4;i++){ if(next[root][i]==-1 ){ next[root][i]=root; } else{ fail[next[root][i] ]=root; rear++; q[rear]=next[root][i]; } } while(front<=rear){ int x=q[front]; val[x]|=val[fail[x] ]; front++; for(i=0;i<4;i++){ if(next[x][i]==-1){ next[x][i]=next[fail[x] ][i]; } else{ fail[next[x][i] ]=next[fail[x] ][i]; rear++; q[rear]=next[x][i]; } } } } void solve(){ int i,j,state,t,state1; for(j=0;j<=sz;j++){ for(state=0;state<(1<<n);state++){ dp[0][j][state]=dp[1][j][state]=-inf; } } int tot=0; dp[tot][0][0]=0; for(i=0;i<m;i++){ for(j=0;j<=sz;j++){ for(state=0;state<(1<<n);state++){ if(dp[tot][j][state]==-inf)continue; for(t=0;t<4;t++){ state1=(state|val[next[j][t] ]); dp[1^tot ][next[j][t] ][state1]=max(dp[1^tot ][next[j][t] ][state1],w[state1] ); } } } tot=1^tot; for(j=0;j<=sz;j++){ for(state=0;state<(1<<n);state++){ dp[1^tot][j][state]=-inf; } } } int maxx=-inf; for(j=0;j<=sz;j++){ for(state=0;state<(1<<n);state++){ maxx=max(maxx,dp[tot][j][state]); } } if(maxx<0){ printf("No Rabbit after 2012!\n"); } else printf("%d\n",maxx); }}ac;int main(){ int i,j; int value[20],len,state; while(scanf("%d%d",&n,&m)!=EOF) { ac.init(); for(i=1;i<=n;i++){ scanf("%s%d",&s,&value[i]); len=strlen(s); if(len>m)continue; ac.charu(s,i); } for(state=0;state<(1<<n);state++){ w[state]=0; for(i=1;i<=n;i++){ if(state&(1<<(i-1) )){ w[state]+=value[i]; } } } ac.build(); ac.solve(); } return 0;}
- zoj3545Rescue the Rabbit (AC自动机+状压dp+滚动数组)
- hdu4057 Rescue the Rabbit【AC自动机+dp滚动数组】
- HDU 4057 Rescue the Rabbit 【AC自动机+状压DP】
- hdu4057 Rescue the Rabbit(AC自动机+DP)
- zoj 3545 - Rescue the Rabbit(AC自动机+dp)
- ZOJ3545---Rescue the Rabbit(AC自动机+dp)
- hdu 4057 Rescue the Rabbit AC自动机+DP
- Zoj 3545 Rescue the Rabbit(ac自动机+dp)
- hdu4057 Rescue the Rabbit,AC自动机,状态压缩dp
- HDU 4057 Rescue the Rabbit (AC自动机+DP)
- 2011 Asia Dalian Regional Contest _ Rescue the Rabbit AC自动机+状压DP
- HDU 4057 Rescue the Rabbit(11年大连,AC自动机+状态压缩DP)
- HDOJ 4057 - Rescue the Rabbit 简单的AC自动机+状态压缩DP
- ZOJ 3545 Rescue the Rabbit AC自动机 + DP (2011大连区域赛G题)
- Hdu 4057 Rescue the Rabbit (AC自动机+状态压缩dp) - 2011 ACM-ICPC Dalian Regional Contest Problem G
- hdu2825-(AC自动机+状压DP)
- HDU3247-(AC自动机+spfa+状压dp)
- bzoj1030(ac自动机+dp)
- OC-NSString从文件中读取字符串
- 《计算机硬件体系及IO优化》
- Educational Codeforces Round 4 612D The Union of k-Segments(stl)
- 串行 RapidIO: 高性能嵌入式互连技术
- Java设计模式(二十三)----解释器模式
- zoj3545Rescue the Rabbit (AC自动机+状压dp+滚动数组)
- 深度学习与人脸识别系列(2)__深度学习的环境搭建(ubuntu+caffe)
- usaco 1.4.2 milk3
- uva10635 - Prince and Princess
- PAT1008数组元素循环右移
- 万能的Dialog
- PAT1031
- 用Docker运行Percona Server
- git使用入门篇