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

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;
}

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/116254.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 解决443/80端口被占用情况

    解决443/80端口被占用情况查找占用端口软件两种方法第一种查看当前进程连接情况 netstat ano 找到占用 443 或者 80 端口的软件 我这已经被我杀掉了 所以没有 就只是举个例子 介绍下方法 通过找到的进程号 然后就可以到任务管理器里面结束掉 第二种 1 查看指定端口 我这举例图片用的 445 端口 连接情况 netstat ano findstr 80 2 查看指定进程 此处查的 PID4 ta

    2025年10月6日
    3
  • navcat15激活码_在线激活

    (navcat15激活码)本文适用于JetBrains家族所有ide,包括IntelliJidea,phpstorm,webstorm,pycharm,datagrip等。IntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,下面是详细链接哦~https://javaforall.net/100143.html…

    2022年3月25日
    90
  • Spring和SpringMVC以及SpringBoot的区别

    Spring和SpringMVC以及SpringBoot的区别Spring是一个开源框架,为简化企业级应用开发而生。Spring可以是使简单的JavaBean实现以前只有EJB才能实现的功能。Spring是一个IOC和AOP容器框架。Spring容器的主要核心是:控制反转(IOC),传统的java开发模式中,当需要一个对象时,我们会自己使用new或者getInstance等直接或者间接调用构造方法创建一个对象。而在…

    2022年5月20日
    43
  • android的WebView进度条

    android的WebView进度条

    2021年8月22日
    75
  • system函数,WIFEXITED和WEXITSTATUS

    system函数,WIFEXITED和WEXITSTATUS1,在程序中,用exit来设置进程的退出值时,虽然该函数的参数类型为int型,但再父进程中只能取到其值的低8位.所以用exit返回值时,高于255的值是没有意义的.2,对于system函数,返回值是由两部分组成的,低8位值表示所执行的脚本在执行过程中所接收到的信号值,其余的位表示的脚本exit退出时所设置的值,即脚本内exit退出是的值的低8位,在system返回值的低9-1

    2025年6月21日
    5
  • sublime怎么运行php(sublime运行python)

    前言:我用的是phpstudy安装包,安装php环境,因为是个人PC也没什么敏感文件,所以用phpstudy安装环境是可以的。phpstudy存在安全问题,之前也讨论过了。我用的是sublime编辑器,美观,配置环境稍微有点烦。配置步骤下载、安装phpstudy官网安装时注意不要选择中文安装目录,否则报错,Apache无法启动。安装后找到目录php.exe的所在目录,复制这个路

    2022年4月15日
    175

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号