zoukankan      html  css  js  c++  java
  • hdu 4057 Rescue the Rabbit(AC自动机+状压dp)

    题目链接:hdu 4057 Rescue the Rabbit

    题意:

    给出一些模式串,每个串有一定的价值,现在构造一个长度为M的串,问最大的价值为多少,每个模式串最多统计一次。

    题解:

    由于每个模式串最多统计一次,所以我们要考虑记录是否已经存在该串。

    考虑dp[i][j][k]表示当前考虑到i的长度,存在的串的组合为j,在AC自动机上走到了k这个节点的状态。

    然后转移一下就能将所有能到达的状态走到。然后取一个最大值就行了。

     1 #include<bits/stdc++.h>
     2 #define mst(a,b) memset(a,b,sizeof(a))
     3 #define F(i,a,b) for(int i=(a);i<=(b);++i)
     4 using namespace std;
     5 
     6 const int AC_N=20000,tyn=4;
     7 struct AC_automation{
     8     int tr[AC_N][tyn],cnt[AC_N],Q[AC_N],fail[AC_N],tot;
     9     inline int getid(char x)
    10     {
    11         if(x=='A')return 0;
    12         if(x=='T')return 1;
    13         if(x=='G')return 2;
    14         return 3;
    15     }
    16     void nw(){cnt[++tot]=0,fail[tot]=0;memset(tr[tot],0,sizeof(tr[tot]));}
    17     void init(){tot=-1,fail[0]=-1,nw();}
    18     void insert(char *s,int idx,int x=0){
    19         for(int len=strlen(s),i=0,w;i<len;x=tr[x][w],i++)
    20             if(!tr[x][w=getid(s[i])])nw(),tr[x][w]=tot;
    21         cnt[x]|=1<<(idx-1);
    22     }
    23     void build(int head=1,int tail=0){
    24         for(int i=0;i<tyn;i++)if(tr[0][i])Q[++tail]=tr[0][i];
    25         while(head<=tail)for(int x=Q[head++],i=0;i<tyn;i++)
    26             if(tr[x][i])
    27             {
    28                 fail[tr[x][i]]=tr[fail[x]][i],Q[++tail]=tr[x][i];
    29                 cnt[tr[x][i]]|=cnt[fail[tr[x][i]]];
    30             }
    31             else tr[x][i]=tr[fail[x]][i];
    32     }
    33 }AC;
    34 
    35 int dp[2][1<<10][1001],n,m,val[20],now,U,ans;
    36 char s[1000];
    37 
    38 int getans(int u)
    39 {
    40     int ans=0;
    41     for(int i=1;u;u>>=1,i++)if(u&1)ans+=val[i];
    42     return ans;
    43 }
    44 
    45 int main(){
    46     while(~scanf("%d%d",&n,&m))
    47     {
    48         now=0,ans=-INT_MAX;AC.init();
    49         F(i,1,n)
    50         {
    51             scanf("%s%d",s,val+i);
    52             AC.insert(s,i);
    53         }
    54         AC.build(),U=(1<<n)-1;
    55         mst(dp[now],0),dp[now][0][0]=1;
    56         F(i,1,m)
    57         {
    58             now^=1,mst(dp[now],0);
    59             F(r,0,U)F(j,0,AC.tot)
    60             if(dp[now^1][r][j])
    61                 F(k,0,3)dp[now][r|AC.cnt[AC.tr[j][k]]][AC.tr[j][k]]=1;
    62         }
    63         F(j,0,U)F(i,0,AC.tot)if(dp[now][j][i]){ans=max(ans,getans(j));break;}
    64         if(ans>=0)printf("%d
    ",ans);
    65         else puts("No Rabbit after 2012!");
    66     }
    67     return 0;
    68 }
    View Code
  • 相关阅读:
    我的第一篇博客
    汇编语言——基础知识 Cop
    汇编语言第二章实验 Cop
    什么是<!DOCTYPE html>
    python第三方模块安装的几个方式
    linux下安装memcacheQ
    python正则表达式
    边框背景
    伪类
    属性选择符和样式
  • 原文地址:https://www.cnblogs.com/bin-gege/p/7252617.html
Copyright © 2011-2022 走看看