zoukankan      html  css  js  c++  java
  • Zoj 3545 Rescue the Rabbit(ac自己主动机+dp)

    标题效果:

    鉴于DNA有一个正确的顺序值。请构造一个长度I的DNA在这个序列使DNA正确的顺序值极大。它被认为是负的输出噼啪。

    。。


    IDEAS:

    施工顺序是,ac己主动机上走,求最大要用到dp

    dp[i][j][k] 表示如今构造到了长度 i 。

    此时的我们把当前字符放在j节点。而且满足了k状态。k是一个10位的2进制状态压缩。

    注意这道题上有坑就是一个序列可能有多个权值。

    所以不能直接赋值。须要用位或。


    #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
    ",ans);
            else puts("No Rabbit after 2012!");
        }
        return 0;
    }
    
    


    版权声明:本文博主原创文章,博客,未经同意不得转载。

  • 相关阅读:
    类(抽象类与非抽象类)和接口
    Arduino学习——u8glib提供的字体样式
    Arduino学习——u8glib库资料整理
    Arduino学习——Arduino main 函数
    全局变量的初始化
    nmake学习笔记2
    Big Endian与Litter Endian
    nmake学习笔记
    重载操作符
    offsetof的意义
  • 原文地址:https://www.cnblogs.com/lcchuguo/p/4908542.html
Copyright © 2011-2022 走看看