zoukankan      html  css  js  c++  java
  • hdu4057 Rescue the Rabbit(AC自己主动机+DP)

    Rescue the Rabbit

    Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)

    Total Submission(s): 1412 Accepted Submission(s): 403


    Problem Description
    Dr. X is a biologist, who likes rabbits very much and can do everything for them. 2012 is coming, and Dr. X wants to take some rabbits to Noah's Ark, or there are no rabbits any more.

    A rabbit's genes can be expressed as a string whose length is l (1 ≤ l ≤ 100) containing only 'A', 'G', 'T', 'C'. There is no doubt that Dr. X had a in-depth research on the rabbits' genes. He found that if a rabbit gene contained a particular gene segment, we could consider it as a good rabbit, or sometimes a bad rabbit. And we use a value W to measure this index.

    We can make a example, if a rabbit has gene segment "ATG", its W would plus 4; and if has gene segment "TGC", its W plus -3. So if a rabbit's gene string is "ATGC", its W is 1 due to ATGC contains both "ATG"(+4) and "TGC"(-3). And if another rabbit's gene string is "ATGATG", its W is 4 due to one gene segment can be calculate only once.

    Because there are enough rabbits on Earth before 2012, so we can assume we can get any genes with different structure. Now Dr. X want to find a rabbit whose gene has highest W value. There are so many different genes with length l, and Dr. X is not good at programming, can you help him to figure out the W value of the best rabbit.

    Input
    There are multiple test cases. For each case the first line is two integers n (1 ≤ n ≤ 10),l (1 ≤ l ≤ 100), indicating the number of the particular gene segment and the length of rabbits' genes.

    The next n lines each line contains a string DNAi and an integer wi (|wi| ≤ 100), indicating this gene segment and the value it can contribute to a rabbit's W.

    Output
    For each test case, output an integer indicating the W value of the best rabbit. If we found this value is negative, you should output "No Rabbit after 2012!".

    Sample Input
    2 4 ATG 4 TGC -3 1 6 TGC 4 4 1 A -1 T -2 G -3 C -4

    Sample Output
    4 4 No Rabbit after 2012!
    Hint
    case 1:we can find a rabbit whose gene string is ATGG(4), or ATGA(4) etc. case 2:we can find a rabbit whose gene string is TGCTGC(4), or TGCCCC(4) etc. case 3:any gene string whose length is 1 has a negative W.

    Author
    HONG, Qize

    Source

    Recommend
    lcy | We have carefully selected several similar problems for you:4053 4056 4059 4052 4051

    顶层模型:AC自己主动机。状态转移

    解题思路:用dp[i][j][k]表示长度为i,状态为j,n个串状态为k的最大值。
    注意两点:1.题目中每一个串仅仅记一次。所以每次走fail指针,把符合要求的累加就可以。
    2.dp数组大小为100*1000*1024开不下,用滚动数组避免MLE。


    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <queue>
    #define inf 1000000000
    using namespace std;
    int n,l,w;
    char s[110];
    int L,rt,next[1010][26],end[1010],fail[1010],c[1010];
    int dp[2][1010][1<<10];
    int newnode(){
        memset(next[L],0,sizeof next[L]);
        c[L]=0;
        end[L++]=0;
        return L-1;
    }
    void init(){
        L=0;
        rt=newnode();
    }
    void insert(char *s,int z,int x){
        int le=strlen(s),now=rt;
        for(int i=0;i<le;i++){
            int x=s[i]-'A';
            if(!next[now][x]) next[now][x]=newnode();
            now=next[now][x];
        }
        end[now]+=z;
        c[now]|=(1<<x);
    }
    void build(){
        queue<int> q;
        int x=rt;
        for(int i=0;i<26;i++){
            if(next[x][i]){
                fail[next[x][i]]=rt;
                q.push(next[x][i]);
            }
        }
        while(!q.empty()){
            x=q.front();
            q.pop();
            for(int i=0;i<26;i++){
                if(!next[x][i]){
                    next[x][i]=next[fail[x]][i];
                }else{
                    fail[next[x][i]]=next[fail[x]][i];
                    q.push(next[x][i]);
                }
            }
        }
    }
    void read(){
        for(int i=0;i<n;i++){
            scanf("%s %d",s,&w);
            insert(s,w,i);
        }
    }
    int f[4]={0,2,6,19};
    void solve(){
        build();
        int cur=0;
        for(int j=0;j<L;j++){
            for(int k=0;k<(1<<n);k++) dp[cur][j][k]=-inf;
        }
        dp[cur][0][0]=0;
        int ans=-inf;
        for(int i=1;i<=l;i++){
            for(int j=0;j<L;j++){
                for(int k=0;k<(1<<n);k++) dp[1-cur][j][k]=-inf;
            }
            for(int j=0;j<L;j++){
                for(int k=0;k<(1<<n);k++){
                    if(dp[cur][j][k]==-inf) continue;
                    for(int p=0;p<4;p++){
                        int z=f[p],nxt=next[j][z];
                        int C=0,tmp=0,x=nxt;
                        while(x){
                            C|=c[x];
                            if((k&c[x])==0) tmp+=end[x];
                            x=fail[x];
                        }
                        dp[1-cur][nxt][k|C]=max(dp[1-cur][nxt][k|C],dp[cur][j][k]+tmp);
                    }
                }
            }
            cur=1-cur;
            if(i==l){
                for(int j=0;j<L;j++){
                    for(int k=0;k<(1<<n);k++){
                        ans=max(ans,dp[cur][j][k]);
                    }
                }
            }
        }
        if(ans<0) puts("No Rabbit after 2012!");
        else printf("%d
    ",ans);
    }
    int main(){
        while(~scanf("%d%d",&n,&l)){
            init();
            read();
            solve();
        }
        return 0;
    }
    


  • 相关阅读:
    Django CBV和FBV
    ArcGIS案例学习笔记2_1_山顶点提取最大值提取
    ArcGIS案例学习笔记2_1_学校选址适宜性分析
    ArcGIS案例学习笔记_3_2_CAD数据导入建库
    ArcGIS案例学习笔记3_1_地理配准案例_目视找点
    ArcGIS案例学习笔记3_1_地理配准案例_图面控制点
    ArcGIS案例学习笔记3_1_ArcMap编辑练习
    ArcGIS案例学习笔记4_2_城乡规划容积率计算和建筑景观三维动画
    ArcGIS案例学习笔记4_2_水文分析批处理地理建模
    ArcGIS案例学习笔记4_1_矢量校正
  • 原文地址:https://www.cnblogs.com/yjbjingcha/p/6910000.html
Copyright © 2011-2022 走看看