HDU 3341 lost's revenge (AC automation + dp + hash)

Source: Internet
Author: User

Question:

Given a lot of DNA strings, the value of each string is 1, and finally a long string. You need to rearrange the final string to make it the weight and maximum of all its substrings.


Train of Thought Analysis:

Search is the first idea that is easy to think! 3721 for her .. Directly one character and one character, and then judge the final weight on the AC automatic machine. Tle yo.

Then find that the search fails, then DP. It is easy to think that DP [I] [a] [B] [C] [d] indicates that the node traversing the AC automatic machine is in I, and then a, the weight of B G, C, and D T.

Another look at the memory, 500*40*40*40*40... then... No.

Think about it, because it is about the length of the string is 40, so the maximum state is 10*10*10*10 .., Therefore, opening 40 ^ 4 is a waste. So hash the status.

About hash... CNT [0]-CNT [3] indicates the number of acgt. Now, the ABC acgt is a * (CNT [3] + 1) * (CNT [2] + 1) * (CNT [1] + 1) + B * (CNT [2] + 1) * (CNT [1] + 1) + C * (CNT [1] + 1) + D * 1


Then follow the preceding five-dimensional DP. Point is .. There are repeated strings, and there is no basic trust between people.


#include <cstdio>#include <iostream>#include <cstring>#include <algorithm>#include <utility>#define inf 0x3f3f3f3f#include <vector>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){    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++;}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(){    for(int i=0;i<idx;i++)        free(&ac[i]);}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("");    }}char word[50];int cnt[5];int dp[515][11*11*11*11+5];int bit[5];int solve(){    memset(dp,-1,sizeof dp);    dp[0][0]=0;    bit[0]=(cnt[1]+1)*(cnt[2]+1)*(cnt[3]+1);    bit[1]=(cnt[2]+1)*(cnt[3]+1);    bit[2]=(cnt[3]+1);    bit[3]=1;    for(int A=0;A<=cnt[0];A++)    {        for(int B=0;B<=cnt[1];B++)        {            for(int C=0;C<=cnt[2];C++)            {                for(int D=0;D<=cnt[3];D++)                {                    int state=A*bit[0]+B*bit[1]+C*bit[2]+D*bit[3];                    for(int i=0;i<idx;i++)                    {                        if(dp[i][state]>=0)                        {                            for(int k=0;k<4;k++)                            {                                if(k==0 && A==cnt[0])continue;                                if(k==1 && B==cnt[1])continue;                                if(k==2 && C==cnt[2])continue;                                if(k==3 && D==cnt[3])continue;                                dp[ac[i].next[k]->index][state+bit[k]]=max(dp[ac[i].next[k]->index][state+bit[k]],dp[i][state]+ac[i].next[k]->isword);                            }                        }                    }                }            }        }    }    int ans=0;    int tag=cnt[0]*bit[0]+cnt[1]*bit[1]+cnt[2]*bit[2]+cnt[3]*bit[3];    for(int i=0;i<idx;i++)        ans=max(ans,dp[i][tag]);    return ans;}int main(){    rev['A']=0;    rev['C']=1;    rev['G']=2;    rev['T']=3;    int n,cas=1;    while(scanf("%d",&n)!=EOF && n)    {        idx=0;        trie *root = New();        for(int i=1;i<=n;i++)        {            scanf("%s",word);            Insert(root,word,strlen(word));        }        acbuild(root);        scanf("%s",word);        int len=strlen(word);        memset(cnt,0,sizeof cnt);        for(int j=0;j<len;j++)            cnt[rev[word[j]]]++;        printf("Case %d: %d\n",cas++,solve());    }    return 0;}


HDU 3341 lost's revenge (AC automation + dp + hash)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.