Hdu 4057 AC自动机+DP

其实是个垃圾题,但是当时我不会AC自动机。
写了几个板题之后这个板子我已经会背了,于是随便写写就1A了。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <iostream>
using namespace std;

int n, l;
char s[1050];
int w[20];

struct Trie{
    int ch[1005][4];
    int end[1005];
    int fail[1005];
    int sz;
    int idx(char a){
        if(a=='A')return 0;
        if(a=='G')return 1;
        if(a=='C')return 2;
        if(a=='T')return 3;
        return 4;
    }
    int newnode(){
        for(int i=0;i<4;i++)ch[sz][i]=-1;
        end[sz]=-1;
        return sz++;
    }
    void init(){
        sz=0;
        newnode();
    }
    void insert(char s[], int id){
        int len=strlen(s);
        int u=0;
        for(int i=0;i<len;i++){
            if(ch[u][idx(s[i])]==-1)ch[u][idx(s[i])]=newnode();
            u=ch[u][idx(s[i])];
        }
        end[u]=id;
    }
    void build(){
        fail[0]=0;
        queue<int>q;
        for(int i=0;i<4;i++){
            if(ch[0][i]==-1){
                ch[0][i]=0;
            }
            else {
                fail[ch[0][i]]=0;
                q.push(ch[0][i]);
            }
        }
        while(!q.empty()){
            int u=q.front();
            q.pop();
            for(int i=0;i<4;i++){
                if(ch[u][i]==-1){
                    ch[u][i]=ch[fail[u]][i];
                }
                else {
                    fail[ch[u][i]]=ch[fail[u]][i];
                    q.push(ch[u][i]);
                }
            }
        }
    }
};

Trie T;

bool dp[2][1050][1050];

int main()
{
    while(~scanf("%d%d", &n, &l)){
        T.init();
        for(int i=1;i<=n;i++){
            scanf("%s%d", s, &w[i]);
            if((int)strlen(s)>l)continue;
            T.insert(s, i-1);
        }
        T.build();
        memset(dp, false, sizeof(dp));
        dp[0][0][0]=true;
        for(int i=0;i<l;i++){
            int u=i%2;
            memset(dp[u^1], false, sizeof(dp[u^1]));
            for(int j=0;j<T.sz;j++){
                for(int k=0;k<(1<<n);k++){
                    if(dp[u][j][k]){
                        for(int c=0;c<4;c++){
                            int to=T.ch[j][c];
                            int kto=k;
                            int tmp=to;
                            while(tmp){
                                if(T.end[tmp]!=-1){
                                    kto|=(1<<T.end[tmp]);
                                }
                                tmp=T.fail[tmp];
                            }
                            dp[u^1][to][kto]=true;
                        }
                    }
                }
            }
        }
        int M=-100000;
        for(int i=0;i<T.sz;i++){
            for(int j=0;j<(1<<n);j++){
                if(dp[l%2][i][j]){
                    int tmp=0;
                    for(int k=0;k<n;k++){
                        if(j&(1<<k)){
                            tmp+=w[k+1];
                        }
                    }
                    M=max(M, tmp);
                }
            }
        }
        if(M<0)printf("No Rabbit after 2012!\n");
        else printf("%d\n", M);
    }
}

猜你喜欢

转载自blog.csdn.net/mrbird_to_fly/article/details/74015066