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)
上一篇 2022年1月23日 下午11:00
下一篇 2022年1月23日 下午11:00


相关推荐

  • 最短路径模板+解析——(FLoyd算法)[通俗易懂]

    最短路径模板+解析——(FLoyd算法)[通俗易懂]对于无权的图来说:若从一顶点到另一顶点存在着一条路径,则称该路径长度为该路径上所经过的边的数目,它等于该路径上的顶点数减1。由于从一顶点到另一顶点可能存在着多条路径,每条路径上所经过的边数可能不同,即路径长度不同,我们把路径长度最短(即经过的边数最少)的那条路径叫做最短路径,其路径长度叫做最短路径长度或最短距离。对于带权的图来说:考虑路径上各边上的权值,则通常把…

    2022年4月20日
    70
  • sql server 与mysql的区别_sql server的优缺点

    sql server 与mysql的区别_sql server的优缺点最近在自学jsp,这就少不了和数据库打交道啊,相信大家对SQLserver和MySQL不陌生吧。在视频上老师用的是sqlserver数据库,但是我用的时候却是mysql数据库,可真的是吃了不少的苦头啊。直接上代码吧62至64行代码要实现的是查询的是第几个页面的内容,按照sqlserver的查询语法是完全没有问题的,否则代码上直接显示红色了。但是就在启动tomcat的时…

    2022年10月2日
    4
  • php 工厂方法模式

    php 工厂方法模式

    2022年7月25日
    11
  • webgame开发中的文件加密

    webgame开发中的文件加密一般的webgame中都会对资源、消息进行加密,这里只是简单记录一下对文件的加密过程。上图为实际项目中所使用的加密工具(较为简单的一个air项目)输入加密key+需要加密的文件–>加密–>将加密后的文件保存至另一目录(后缀名视自己的项目的规则进行修改)实现步骤:1、读取文件(flash.filesystem.File),获取文件流(…

    2022年6月4日
    43
  • 2021年Vue最常见的面试题以及答案(面试必过)[通俗易懂]

    2021年Vue最常见的面试题以及答案(面试必过)[通俗易懂]这里写目录标题对MVVM的理解?Vue数据双向绑定原理Vue的响应式原理vue中组件的data为什么是一个函数vue中created与mounted区别Vue中computed与method的区别Vue中watch用法详解Vue中常用的一些指令说说vue的生命周期对MVVM的理解?MVVM由Model、View、ViewModel三部分构成,Model层代表数据模型,也可以在Model中定义数据修改和操作的业务逻辑;View代表UI组件,它负责将数据模型转化成UI展现出来;ViewMode

    2022年5月31日
    112
  • ARM方案公司,三星S5PV210核心板,「建议收藏」

    ARM方案公司,三星S5PV210核心板,「建议收藏」核心业务:高通、MTK、三星等解决方案定制开发

    2022年10月14日
    4

发表回复

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

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