zoukankan      html  css  js  c++  java
  • hdu4057 Rescue the Rabbit

    地址:http://acm.hdu.edu.cn/showproblem.php?pid=4057

    题目:

    Rescue the Rabbit

    Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 2233    Accepted Submission(s): 653


    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
     

     思路:

      dp[i][j][s]表示长度为i的串走到第j个节点时状态为s时是否可行。

      如果用dp[i][j][s] 表示长度为i的串走到第j个节点时状态为s时的最小花费会Tle,因为常数会大十倍

      而且需要状压,不然mle。

      1 #include <queue>
      2 #include <cstring>
      3 #include <cstdio>
      4 using namespace std;
      5 
      6 const int INF=0x3f3f3f3f;
      7 struct AC_auto
      8 {
      9     const static int LetterSize = 4;
     10     const static int TrieSize = LetterSize * ( 1e3 + 50);
     11 
     12     int tot,root,fail[TrieSize],end[TrieSize],next[TrieSize][LetterSize];
     13     bool dp[2][TrieSize][1<<10];
     14     int newnode(void)
     15     {
     16         memset(next[tot],-1,sizeof(next[tot]));
     17         end[tot] = 0;
     18         return tot++;
     19     }
     20 
     21     void init(void)
     22     {
     23         tot = 0;
     24         root = newnode();
     25     }
     26 
     27     int getidx(char x)
     28     {
     29         if(x=='A') return 0;
     30         else if(x=='C') return 1;
     31         else if(x=='G') return 2;
     32         return 3;
     33     }
     34 
     35     void insert(char *ss,int x)
     36     {
     37         int len = strlen(ss);
     38         int now = root;
     39         for(int i = 0; i < len; i++)
     40         {
     41             int idx = getidx(ss[i]);
     42             if(next[now][idx] == -1)
     43                 next[now][idx] = newnode();
     44             now = next[now][idx];
     45         }
     46         end[now]|=x;
     47     }
     48 
     49     void build(void)
     50     {
     51         queue<int>Q;
     52         fail[root] = root;
     53         for(int i = 0; i < LetterSize; i++)
     54             if(next[root][i] == -1)
     55                 next[root][i] = root;
     56             else
     57                 fail[next[root][i]] = root,Q.push(next[root][i]);
     58         while(Q.size())
     59         {
     60             int now = Q.front();Q.pop();
     61             for(int i = 0; i < LetterSize; i++)
     62             if(next[now][i] == -1)   next[now][i] = next[fail[now]][i];
     63             else
     64             {
     65                  fail[next[now][i]] = next[fail[now]][i];
     66                  end[next[now][i]]|=end[fail[next[now][i]]];
     67                  Q.push(next[now][i]);
     68             }
     69         }
     70     }
     71 
     72     int match(char *ss)
     73     {
     74         int len,now,res;
     75         len = strlen(ss),now = root,res = 0;
     76         for(int i = 0; i < len; i++)
     77         {
     78             int idx = getidx(ss[i]);
     79             int tmp = now = next[now][idx];
     80             while(tmp)
     81             {
     82                 res += end[tmp];
     83                 end[tmp] = 0;//°´ÌâÄ¿ÐÞ¸Ä
     84                 tmp = fail[tmp];
     85             }
     86         }
     87         return res;
     88     }
     89 
     90     int go(int n,int m,int *v)
     91     {
     92         int ans=-0x3f3f3f3f,now=1,pre=0;
     93         memset(dp[pre],0,sizeof dp[pre]);
     94         dp[0][0][0]=1;
     95         for(int i=0,mx=1<<m;i<n;i++)
     96         {
     97             memset(dp[now],0,sizeof dp[now]);
     98             for(int j=0;j<tot;j++)
     99             for(int s=0;s<mx;s++)
    100             for(int k=0;dp[pre][j][s]&&k<LetterSize;k++)
    101                 dp[now][next[j][k]][s|end[next[j][k]]]=1;
    102             swap(now,pre);
    103         }
    104         for(int i=0,mx=1<<m;i<tot;i++)
    105         for(int j=0;j<mx;j++)
    106         if(dp[pre][i][j])
    107         {
    108             int tmp=0;
    109             for(int k=0;k<m;k++)
    110             if(j&(1<<k))
    111                 tmp+=v[k];
    112             ans=max(ans,tmp);
    113         }
    114         return ans;
    115     }
    116     void debug()
    117     {
    118         for(int i = 0;i < tot;i++)
    119         {
    120             printf("id = %3d,fail = %3d,end = %3d,chi = [",i,fail[i],end[i]);
    121             for(int j = 0;j < LetterSize;j++)
    122                 printf("%3d",next[i][j]);
    123             printf("]
    ");
    124         }
    125     }
    126 };
    127 AC_auto ac;
    128 char ss[2000];
    129 int v[200];
    130 int main(void)
    131 {
    132     //freopen("in.acm","r",stdin);
    133     int n,m;
    134     while(~scanf("%d%d",&m,&n))
    135     {
    136         ac.init();
    137         for(int i=0;i<m;i++)
    138             scanf("%s%d",ss,v+i),ac.insert(ss,1<<i);
    139         ac.build();
    140         int ans=ac.go(n,m,v);
    141         if(ans<0) printf("No Rabbit after 2012!
    ");
    142         else printf("%d
    ",ans);
    143     }
    144     return 0;
    145 }
  • 相关阅读:
    看了支付宝账单,我才知道我是『有钱人』
    用 Pytest+Allure 生成漂亮的 HTML 图形化测试报告
    测试开发城市群,第一站深圳,我们来了!
    测试工作常用 Linux/ Shell 命令之 Bash 逻辑控制基础
    性能测试实战 | JMeter 录制/回放做 App 后端性能压测
    测试圣诞狂欢,万元红包、冲榜豪礼等你拿!
    自动化测试工具 or 自动化策略?孰轻孰重?
    Java 面试题
    疫情之下,普通人高薪就业指南:方向对了,路就不会遥远!
    SharePoint WebPart:扩展SharePoint 2007中图片展示功能
  • 原文地址:https://www.cnblogs.com/weeping/p/7447707.html
Copyright © 2011-2022 走看看