Question:
The given DNA sequence has a weight value. Please construct a DNA sequence with the length of I to maximize the weight of this DNA sequence. If it is a negative number, the output will crash...
Train of Thought Analysis:
The construction sequence is taken on the AC automatic machine, and the DP is used to obtain the maximum value.
DP [I] [J] [k] indicates that the length I is constructed now. At this time, we place the current character on the J node, and the K State is satisfied. K is a 10-bit binary state compression.
Note that a sequence may have multiple weights. Therefore, values cannot be directly assigned. bitwise OR is required.
#include <cstdio>#include <iostream>#include <cstring>#include <algorithm>#include <utility>#define inf 0x3f3f3f3f#define debug puts("fuck")using namespace std;const char tab = 0;const int max_next = 4;int idx;struct trie{ struct trie *fail; struct trie *next[max_next]; int isword; int index;};int rev[256];trie *que[100005],ac[100005];int head,tail;trie *New(){ trie *temp=&ac[idx]; for(int i=0;i<max_next;i++)temp->next[i]=NULL; temp->fail=NULL; temp->isword=0; temp->index=idx++; return temp;}void Insert(trie *root,char *word,int len,int ind){ trie *t=root; for(int i=0;i<len;i++){ if(t->next[rev[word[i]]]==NULL) t->next[rev[word[i]]]=New(); t=t->next[rev[word[i]]]; } t->isword|=(1<<(ind-1));}void acbuild(trie *root){ int head=0,tail=0; que[tail++]=root; root->fail=NULL; while(head<tail){ trie *temp=que[head++],*p; for(int i=0;i<max_next;i++){ if(temp->next[i]){ if(temp==root)temp->next[i]->fail=root; else { p=temp->fail; while(p!=NULL){ if(p->next[i]){ temp->next[i]->fail=p->next[i]; break; } p=p->fail; } if(p==NULL)temp->next[i]->fail=root; } if(temp->next[i]->fail->isword)temp->next[i]->isword|=temp->next[i]->fail->isword; que[tail++]=temp->next[i]; } else if(temp==root)temp->next[i]=root; else temp->next[i]=temp->fail->next[i]; } }}void del(trie *root){ for(int i=0;i<max_next;i++) if(root->next[i])del(root->next[i]); free(root);}char word[105];bool dp[1010][1035];bool tmp[1010][1035];int val[15];void tra(){ for(int i=0;i<idx;i++) { if(ac[i].fail!=NULL)printf("fail = %d ",ac[i].fail->index); for(int k=0;k<max_next;k++) printf("%d ",ac[i].next[k]->index); puts(""); }}int solve(int len,int n){ int ans=-0x3f3f3f3f; memset(dp,false,sizeof dp); dp[0][0]=true; for(int i=1;i<=len;i++) { for(int j=0;j<idx;j++) for(int k=0;k<(1<<n);k++) tmp[j][k]=false; for(int j=0;j<idx;j++) { for(int k=0;k<(1<<n);k++) { if(dp[j][k]) { for(int p=0;p<max_next;p++) { int q=ac[j].next[p]->index; int st=k; if(ac[j].next[p]->isword)st|=ac[j].next[p]->isword; tmp[q][st]=true; } } } } for(int j=0;j<idx;j++) for(int k=0;k<(1<<n);k++) { dp[j][k]=tmp[j][k]; } } for(int j=0;j<idx;j++) { for(int k=0;k<(1<<n);k++) { if(dp[j][k]) { int sum=0; for(int p=0;p<n;p++) { if((1<<p)&k)sum+=val[p+1]; } ans=max(ans,sum); } } } return ans;}int main(){ rev['A']=0; rev['T']=1; rev['C']=2; rev['G']=3; int n,I; while(scanf("%d%d",&n,&I)!=EOF) { idx=0; trie *root = New(); for(int i=1;i<=n;i++) { int key; scanf("%s%d",word,&key); if(strlen(word)>I)continue; Insert(root,word,strlen(word),i); val[i]=key; } acbuild(root); int ans=solve(I,n); if(ans>=0)printf("%d\n",ans); else puts("No Rabbit after 2012!"); } return 0;}
Zoj 3545 rescue the rabbit (AC automation + dp)