hdu 4057 AC自动机+状态压缩dp

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

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.
/**
hdu 4057 AC自动机+状态压缩dp
题目大意:给定一些字符串(ATGC组成),同样用该四个字符组成一个长度为l的字符串,若该字符串包含给定串的一个作为子串,那么就要
          加上这个给定串的值,问最后该字符串的最大值为多少
解题思路:建立自动机,然后在上面跑,如果不要求每个串的权值只能获取一次,那么直接跑来跑去的就行,但是因为只能取一次,串很少,
          可以状态压缩DP,dp[i][j][k]记录前i个字符走到j状态并且已经获得的串状态为k时的最优解。滚动数组优化空间
*/
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <vector>
#include <queue>
#include <iostream>
using namespace std;
const int inf=1e9+7;
const int maxn=1005;
int dp[2][maxn][1<<10];
int n,m,val[15];
struct Trie
{
    int next[maxn][4],fail[maxn],_end[maxn];
    int root,L;
    int change(char ch)
    {
        if(ch=='A')return 0;
        else if(ch=='T')return 1;
        else if(ch=='G')return 2;
        return 3;
    }
    int newnode()
    {
        for(int i=0; i<4; i++)
        {
            next[L][i]=-1;
        }
        _end[L++]=0;
        return L-1;
    }
    void init()
    {
        L=0;
        root=newnode();
    }
    void Insert(char *buf,int id)
    {
        int len=strlen(buf);
        int now=root;
        for(int i=0; i<len; i++)
        {
            int q=change(buf[i]);
            if(next[now][q]==-1)
                next[now][q]=newnode();
            now=next[now][q];
        }
        _end[now]|=(1<<id);
    }
    void build()
    {
        queue<int>Q;
        fail[root]=root;
        for(int i=0; i<4; i++)
        {
            if(next[root][i]==-1)
                next[root][i]=root;
            else
            {
                fail[next[root][i]]=root;
                Q.push(next[root][i]);
            }
        }
        while(!Q.empty())
        {
            int now=Q.front();
            Q.pop();
            _end[now]|=_end[fail[now]];
            for(int i=0; i<4; i++)
            {
                if(next[now][i]==-1)
                {
                    next[now][i]=next[fail[now]][i];
                }
                else
                {
                    fail[next[now][i]]=next[fail[now]][i];
                    Q.push(next[now][i]);
                }
            }
        }
    }
    int get(int s)
    {
        int ans=0;
        for(int i=0; i<n; i++)
        {
            if(s&(1<<i))
                ans+=val[i];
        }
        return ans;
    }
    void solve()
    {
        memset(dp,0,sizeof(dp));
        dp[0][0][0]=1;
        for(int i=1; i<=m; i++)
        {
            memset(dp[i&1],0,sizeof(dp[i&1]));
            for(int j=0; j<L; j++)
            {
                for(int k=0; k<4; k++)
                {
                    int x=next[j][k];
                    for(int r=0; r<(1<<n); r++)
                    {
                        if(dp[(i+1)&1][j][r])
                        {
                            dp[i&1][x][r|_end[x]]=1;
                        }
                    }
                }
            }
        }
        int ans=-inf;
        for(int j=0; j<(1<<n); j++)
        {
            for(int i=0; i<L; i++)
            {
                if(dp[m&1][i][j])
                {
                    ans=max(ans,get(j));
                }
            }
        }
        if(ans<0)puts("No Rabbit after 2012!");
        else printf("%d\n",ans);
    }
} t;
char s[1005];
int main()
{
    while(~scanf("%d%d",&n,&m))
    {
        t.init();
        for(int i=0; i<n; i++)
        {
            int x;
            scanf("%s%d",s,&val[i]);
            t.Insert(s,i);
        }
        t.build();
        t.solve();
    }
    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-11-03 18:47:58

hdu 4057 AC自动机+状态压缩dp的相关文章

HDU 4511 (AC自动机+状态压缩DP)

题目链接:  http://acm.hdu.edu.cn/showproblem.php?pid=4511 题目大意:从1走到N,中间可以选择性经过某些点,比如1->N,或1->2->N,但是某些段路径(注意不是某些条)是被禁止的.问从1->N的最短距离. 解题思路: AC自动机部分: 如果只是禁掉某些边,最短路算法加提前标记被禁的边即可. 但是本题是禁掉指定的路段,所以得边走边禁,需要一个在线算法. 所以使用AC自动机来压缩路段,如禁掉的路段是1->2->3,那么in

HDU 3341 Lost&#39;s revenge AC自动机+ 状态压缩DP

题意:这个题目和HDU2457有点类似,都是AC自动机上的状态dp,题意就是给你只含有'A','T','C','G',四个字符的子串和文本串,问你文本串如何排列才可以使得文本串中包含有更多的模式串 解题思路:我们知道了 有 num[0] 个 'A', num[1] 个 ‘T’, num[2] 个 ‘C’,num[3] 个‘G’, 我们的可以知道暴力的思路就是把所有的文本串都枚举出来然后一一匹配.我们膜拜了一下春哥以后,就可以有以下思路:  把一个串的信息压缩一下,把具有同样个数字符的串看成是同一

HDU 2825 Wireless Password (AC自动机 + 状态压缩DP)

题目链接:Wireless Password 解析:给 m 个单词构成的集合,统计所有长度为 n 的串中,包含至少 k 个单词的方案数. AC自动机 + 状态压缩DP. DP[i][j][k]:长度为i的字符串匹配到状态j且包含k个magic word的可能字符串个数. AC代码: #include <algorithm> #include <iostream> #include <cstdio> #include <queue> #include <

POJ 3691 (AC自动机+状态压缩DP)

题目链接:  http://poj.org/problem?id=3691 题目大意:给定N的致病DNA片段以及一个最终DNA片段.问最终DNA片段最少修改多少个字符,使得不包含任一致病DNA. 解题思路: 首先说一下AC自动机在本题中的作用. ①字典树部分:负责判断当前0~i个字符组成的串是否包含致病DNA,这部分靠字典树上的cnt标记完成. ②匹配部分:主要依赖于匹配和失配转移关系的计算,这部分非常重要,用来构建不同字符间状态压缩的转移关系(代替反人类的位运算). 这也是必须使用AC自动机而

hdu 4758 Walk Through Squares(AC自动机+状态压缩DP)

题目链接:hdu 4758 Walk Through Squares 题意: 给你一个n*m的网格,现在你要从(1,1)走到(n,m),每次只能向右走或者向下走,走完后会形成一个包含R,D的序列,这个序列必须要包含题目给出的两个字符串,问有多少种方案. 题解: 由于要从(1,1)走到(n,m),所以这个形成的字符串包含R和D的数量是一定的. 现在考虑dp[u][i][j][k],表示包含两种串的组合状态,走了i个D,走了j个R,走到了k这个AC自动机的节点的方案数,然后dp一下就行了.复杂度为O

【HDU3341】AC自动机状态压缩DP,或者说hash枚举DP,-------出题人卡常数都是狗!!!!!

题意:给若干种个串,再给个主串,然后把主串打乱顺序,使得包含子串尽量多(一种可以有多个,两个之间可以部分重叠).如第一组数据,ACGT,包含AC.CG.GT,三个,输出3.第二组数据A1A2A3,包含A1A2和A2A3两个"AA",答案为2. 其实我并没有AC.我被卡常数TLE了...实在不想写这种没意义的东西了. 贴代码,待填坑. #include <queue> #include <cstdio> #include <cstring> #incl

hdu4758AC自动机+状态压缩DP

http://acm.hdu.edu.cn/showproblem.php?pid=4758 Problem Description On the beaming day of 60th anniversary of NJUST, as a military college which was Second Artillery Academy of Harbin Military Engineering Institute before, queue phalanx is a special l

hdu 2825 aC自动机+状压dp

Wireless Password Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 5640    Accepted Submission(s): 1785 Problem Description Liyuan lives in a old apartment. One day, he suddenly found that there

hdu 3217 Health(状态压缩DP)

Health Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 527    Accepted Submission(s): 145 Problem Description Unfortunately YY gets ill, but he does not want to go to hospital. His girlfriend LM