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
  • 相关阅读:
    21.Merge Two Sorted Lists 、23. Merge k Sorted Lists
    34. Find First and Last Position of Element in Sorted Array
    leetcode 20. Valid Parentheses 、32. Longest Valid Parentheses 、301. Remove Invalid Parentheses
    31. Next Permutation
    17. Letter Combinations of a Phone Number
    android 常见分辨率(mdpi、hdpi 、xhdpi、xxhdpi )及屏幕适配注意事项
    oc 异常处理
    oc 类型判断
    oc Delegate
    oc 协议
  • 原文地址:https://www.cnblogs.com/bin-gege/p/7252617.html
Copyright © 2011-2022 走看看