hdu 3341 Lost's revenge
2012-08-07 09:17
288 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3341
题目大意:给出一些病毒串,一个原串,问怎么调整原串的顺序使得跟最多的病毒串匹配。
题目思路:用dp[a][b][c][d][e]表示分别用了a,b,c,d个碱基,到达e结点的最值。开始加了一个总长度,后来想到既然有总长度,则有一维可以去,但是还是超时,哎,居然没有想到不用总长度直接用4种碱基的长度来表示状态,这样就又可以降低常数了,居然一下就刷到第一了,嘿嘿。。
题目大意:给出一些病毒串,一个原串,问怎么调整原串的顺序使得跟最多的病毒串匹配。
题目思路:用dp[a][b][c][d][e]表示分别用了a,b,c,d个碱基,到达e结点的最值。开始加了一个总长度,后来想到既然有总长度,则有一维可以去,但是还是超时,哎,居然没有想到不用总长度直接用4种碱基的长度来表示状态,这样就又可以降低常数了,居然一下就刷到第一了,嘿嘿。。
#include<stdio.h> #include<stdlib.h> #include<string.h> #include<string> #include<queue> #include<algorithm> #include<vector> #include<stack> #include<list> #include<iostream> #include<map> using namespace std; #define inf 0x3f3f3f3f #define M 110 inline int max(int a,int b) { return a>b?a:b; } int min(int a,int b) { return a<b?a:b; } int num[4]; int cnt; int dp[2][42][42][42][550]; char s[100],str[100]; int mp[1000],q[55*10]; struct node { int cnt,fail; int next[4]; void init() { cnt=fail=0; memset(next,0,sizeof(next)); } }tri[55*10]; void insert(char *s) { int i,p,x; p=0; for(i=0;s[i];i++) { x=mp[s[i]]; if(!tri[p].next[x]) { tri[++cnt].init(); tri[p].next[x]=cnt; } p=tri[p].next[x];//不要等于cnt,只有开辟新节点才等于cnt; } tri[p].cnt++; } void bfs() { int i,p,head,tail,suf; p=head=tail=0; for(i=0;i<4;i++) { if(tri[0].next[i]) { q[tail++]=tri[0].next[i]; tri[q[tail-1]].fail=0; } } while(head<tail) { p=q[head++];suf=tri[p].fail; tri[p].cnt+=tri[suf].cnt; for(i=0;i<4;i++) { if(tri[p].next[i]) { q[tail++]=tri[p].next[i]; tri[q[tail-1]].fail=tri[suf].next[i]; } else tri[p].next[i]=tri[suf].next[i]; } } } void set(int a) { int j,b,c,d,e; for(b=0;b<=num[1];b++) for(c=0;c<=num[2];c++) for(d=0;d<=num[3];d++) for(e=0;e<=cnt;e++) { dp[a][b][c][d][e]=-1; } } void solve(int n) { int tmp,i,j,a,b,c,d,e,pos,ans; tmp=0; set(0); dp[0][0][0][0][0]=0; for(a=0;a<=num[0];a++) { set(tmp^1); for(b=0;b<=num[1];b++) for(c=0;c<=num[2];c++) for(d=0;d<=num[3];d++) { for(e=0;e<=cnt;e++) { if(dp[tmp][b][c][d][e]==-1) continue; pos=tri[e].next[0]; dp[tmp^1][b][c][d][pos]=max(dp[tmp^1][b][c][d][pos],dp[tmp][b][c][d][e]+tri[pos].cnt); pos=tri[e].next[1]; dp[tmp][b+1][c][d][pos]=max(dp[tmp][b+1][c][d][pos],dp[tmp][b][c][d][e]+tri[pos].cnt); pos=tri[e].next[2]; dp[tmp][b][c+1][d][pos]=max(dp[tmp][b][c+1][d][pos],dp[tmp][b][c][d][e]+tri[pos].cnt); pos=tri[e].next[3]; dp[tmp][b][c][d+1][pos]=max(dp[tmp][b][c][d+1][pos],dp[tmp][b][c][d][e]+tri[pos].cnt); } } tmp^=1; } ans=0; for(i=0;i<=cnt;i++) { ans=max(ans,dp[tmp^1][num[1]][num[2]][num[3]][i]); } printf("%d\n",ans); } int main() { int n,i,len,count=1; mp['A']=0;mp['C']=1;mp['G']=2;mp['T']=3; while(scanf("%d",&n),n) { cnt=0; tri[0].init(); for(i=0;i<n;i++) { scanf("%s",str); insert(str); } scanf("%s",s); len=strlen(s); memset(num,0,sizeof(num)); for(i=0;i<len;i++) { num[mp[s[i]]]++; } bfs(); printf("Case %d: ",count++); solve(len); } }
相关文章推荐
- HDU 3341 Lost's revenge
- Hdu 3341 Lost's revenge (ac自动机+dp+hash)
- HDU 3341 Lost's revenge(AC自动机+DP)
- HDU - 3341 Lost's revenge(AC自己主动机+DP)
- HDU 3341 Lost's revenge(AC自动机+状态压缩DP)
- [AC自动机+dp+变进制状压] hdu 3341 Lost's revenge
- Hdu 3341 Lost's revenge (ac+自己主动机dp+hash)
- HDU - 3341 Lost's revenge(AC自动机+DP)
- hdu 3341 Lost's revenge(dp+Ac自动机)
- hdu 3341 Lost's revenge(AC自动机+DP)
- 【HDU】3341 Lost's revenge AC自动机+变进制+DP
- 【AC自动机】 HDOJ 3341 Lost's revenge
- HDU3341 Lost's revenge
- hdu 3341 Lost's revenge
- HDU 3341 Lost's revenge
- hdu 2732 Leapin' Lizards 网络流 拆点构图
- HDU 1210 Eddy's 洗牌问题
- hdu 1160 FatMouse's Speed (LIS)
- hdu 1160 FatMouse's Speed(最大上升子序列dp)
- hdu 1038(ACM steps 1.2.1)Biker's Trip Odometer