标签:else tom problem struct def nta queue 一个 uil
Lost‘s revenge
Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others)
Total Submission(s): 4548 Accepted Submission(s): 1274
#include <stdio.h> #include <algorithm> #include <iostream> #include <string.h> #include <queue> using namespace std; #define INF 0x3f3f3f3f int num[4]; int bit[4]; int dp[11*11*11*11+10][550]; int maxx,end_len; struct Trie { int Next[550][4];//4是这里讨论4个小写字母的情况,根据情况修改 int fail[550],end[550];//end数组表示以该节点结尾的字符串的数量 int root,L;//L用来标记节点序号,以广度优先展开的字典树的序号 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(); } int get_id(char ch) { if(ch==‘A‘)return 0; else if(ch==‘G‘)return 1; else if(ch==‘C‘)return 2; else if(ch==‘T‘)return 3; } void insert(char buf[]) { int len = strlen(buf); int now = root; for(int i = 0;i < len;i++) { if(Next[now][get_id(buf[i])] == -1) //如果未建立当前的后继节点,建立新的节点 Next[now][get_id(buf[i])] = newnode(); now = Next[now][get_id(buf[i])]; } end[now]++;//以该节点结尾的字符串数量增加1 } 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];//该段的最后一个节点匹配后,跳到拥有最大公共后缀的fail节点继续匹配 else { fail[Next[now][i]]=Next[fail[now]][i];//当前节点的fail节点等于它前驱节点的fail节点的后继节点 Q.push(Next[now][i]); } } } void solve() { maxx=0; int maxlen=bit[0]*(num[0]+1); for(int i=0;i<=maxlen+1;i++) for(int j=0;j<L;j++) dp[i][j]=INF; dp[0][0]=0; for(int A=0;A<=num[0];A++) for(int G=0;G<=num[1];G++) for(int C=0;C<=num[2];C++) for(int T=0;T<=num[3];T++) { int s=A*bit[0]+G*bit[1]+C*bit[2]+T*bit[3]; for(int j=0;j<L;j++) { if(dp[s][j]<INF-5) { for(int k=0;k<4;k++) { if(k==0&&A==num[0])continue; else if(k==1&&G==num[1])continue; else if(k==2&&C==num[2])continue; else if(k==3&&T==num[3])continue; if(dp[s+bit[k]][Next[j][k]]==INF) dp[s+bit[k]][Next[j][k]]=dp[s][j]+end[Next[j][k]]; else dp[s+bit[k]][Next[j][k]]=max(dp[s+bit[k]][Next[j][k]],dp[s][j]+end[Next[j][k]]); } } } } int max_len=num[0]*bit[0]+num[1]*bit[1]+num[2]*bit[2]+num[3]*bit[3]; for(int i=0;i<L;i++){ if(dp[max_len][i]<INF-5) maxx=max(dp[max_len][i],maxx); } cout<<maxx<<endl; } }; Trie ac; char buf[110]; int main() { int t,n,ans,len,Case=0; while(scanf("%d",&n)!=EOF) { Case++; if(n==0)break; memset(num,0,sizeof(num)); ac.init(); while(n--) { scanf("%s",buf); ac.insert(buf); } ac.build(); scanf("%s",buf); len=strlen(buf); for(int i=0;i<len;i++) { if(buf[i]==‘A‘) num[0]++; else if(buf[i]==‘G‘) num[1]++; else if(buf[i]==‘C‘) num[2]++; else if(buf[i]==‘T‘) num[3]++; } bit[0]=(num[1]+1)*(num[2]+1)*(num[3]+1); bit[1]=(num[2]+1)*(num[3]+1); bit[2]=(num[3]+1); bit[3]=1; printf("Case %d: ",Case); ac.solve(); } return 0; }
HDU 3341 Lost's revenge(AC自动机+状压DP)
标签:else tom problem struct def nta queue 一个 uil
原文地址:http://www.cnblogs.com/a249189046/p/7603302.html