标签:
http://acm.hdu.edu.cn/showproblem.php?pid=4057
2 4 ATG 4 TGC -3 1 6 TGC 4 4 1 A -1 T -2 G -3 C -4
4 4 No Rabbit after 2012!Hintcase 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.
/** hdu 4057 AC自动机+状态压缩dp 题目大意:给定一些字符串(ATGC组成),同样用该四个字符组成一个长度为l的字符串,若该字符串包含给定串的一个作为子串,那么就要 加上这个给定串的值,问最后该字符串的最大值为多少 解题思路:建立自动机,然后在上面跑,如果不要求每个串的权值只能获取一次,那么直接跑来跑去的就行,但是因为只能取一次,串很少, 可以状态压缩DP,dp[i][j][k]记录前i个字符走到j状态并且已经获得的串状态为k时的最优解。滚动数组优化空间 */ #include <stdio.h> #include <string.h> #include <algorithm> #include <vector> #include <queue> #include <iostream> using namespace std; const int inf=1e9+7; const int maxn=1005; int dp[2][maxn][1<<10]; int n,m,val[15]; struct Trie { int next[maxn][4],fail[maxn],_end[maxn]; int root,L; int change(char ch) { if(ch=='A')return 0; else if(ch=='T')return 1; else if(ch=='G')return 2; return 3; } int newnode() { for(int i=0; i<4; i++) { next[L][i]=-1; } _end[L++]=0; return L-1; } void init() { L=0; root=newnode(); } void Insert(char *buf,int id) { int len=strlen(buf); int now=root; for(int i=0; i<len; i++) { int q=change(buf[i]); if(next[now][q]==-1) next[now][q]=newnode(); now=next[now][q]; } _end[now]|=(1<<id); } void build() { queue<int>Q; fail[root]=root; for(int i=0; i<4; i++) { if(next[root][i]==-1) next[root][i]=root; else { fail[next[root][i]]=root; Q.push(next[root][i]); } } while(!Q.empty()) { int now=Q.front(); Q.pop(); _end[now]|=_end[fail[now]]; for(int i=0; i<4; i++) { if(next[now][i]==-1) { next[now][i]=next[fail[now]][i]; } else { fail[next[now][i]]=next[fail[now]][i]; Q.push(next[now][i]); } } } } int get(int s) { int ans=0; for(int i=0; i<n; i++) { if(s&(1<<i)) ans+=val[i]; } return ans; } void solve() { memset(dp,0,sizeof(dp)); dp[0][0][0]=1; for(int i=1; i<=m; i++) { memset(dp[i&1],0,sizeof(dp[i&1])); for(int j=0; j<L; j++) { for(int k=0; k<4; k++) { int x=next[j][k]; for(int r=0; r<(1<<n); r++) { if(dp[(i+1)&1][j][r]) { dp[i&1][x][r|_end[x]]=1; } } } } } int ans=-inf; for(int j=0; j<(1<<n); j++) { for(int i=0; i<L; i++) { if(dp[m&1][i][j]) { ans=max(ans,get(j)); } } } if(ans<0)puts("No Rabbit after 2012!"); else printf("%d\n",ans); } } t; char s[1005]; int main() { while(~scanf("%d%d",&n,&m)) { t.init(); for(int i=0; i<n; i++) { int x; scanf("%s%d",s,&val[i]); t.Insert(s,i); } t.build(); t.solve(); } return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:
原文地址:http://blog.csdn.net/lvshubao1314/article/details/46801529