zoukankan      html  css  js  c++  java
  • hdu4057Rescue the Rabbit(ac自动机+dp)

    链接

    当时是因为没有做出来这道题才开了自动机的专题,现在看看还是比较简单的。

    因为每个病毒串只算一次,只有10个病毒串,可以状压一下哪些状态是可以达到的,最后取一个最大值。

      1 #include <iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 #include<stdlib.h>
      6 #include<vector>
      7 #include<cmath>
      8 #include<queue>
      9 #include<set>
     10 #include<string>
     11 using namespace std;
     12 #define N 1005
     13 #define LL long long
     14 #define INF 0xfffffff
     15 const double eps = 1e-8;
     16 const double pi = acos(-1.0);
     17 const double inf = ~0u>>2;
     18 const int child_num = 4;
     19 char vir[115];
     20 int v[12];
     21 class AC
     22 {
     23     private:
     24     int ch[N][child_num];
     25     int fail[N];
     26     int Q[N];
     27     int val[N];
     28     int sz;
     29     int id[128];
     30     int dp[2][N][1<<10];
     31     char s[N];
     32     public:
     33     void init()
     34     {
     35         fail[0] = 0;
     36         id['A'] = 0,id['G'] = 1,id['T'] = 2,id['C'] = 3;
     37     }
     38     void reset()
     39     {
     40         memset(ch[0],0,sizeof(ch[0]));
     41         memset(val,0,sizeof(val));
     42         sz = 1;
     43     }
     44     void insert(char *a,int key)
     45     {
     46         int p = 0;
     47         for(; *a ; a++)
     48         {
     49             int d= id[*a];
     50             if(ch[p][d]==0)
     51             {
     52                 memset(ch[sz],0,sizeof(ch[sz]));
     53                 s[sz] = *a;
     54                 ch[p][d] = sz++;
     55             }
     56             p = ch[p][d];
     57         }
     58         val[p] = (1<<key);
     59     }
     60     void construct()
     61     {
     62         int i,head=0,tail = 0;
     63         for(i = 0; i  < child_num ;i++)
     64         {
     65             if(ch[0][i])
     66             {
     67                 fail[ch[0][i]] = 0;
     68                 Q[tail++] = ch[0][i];
     69             }
     70         }
     71         while(head!=tail)
     72         {
     73             int u = Q[head++];
     74             val[u]|=val[fail[u]];
     75             for(i = 0; i < child_num ; i++)
     76             {
     77                 if(ch[u][i])
     78                 {
     79                     fail[ch[u][i]] = ch[fail[u]][i];
     80                     Q[tail++] = ch[u][i];
     81                 }
     82                 else ch[u][i] = ch[fail[u]][i];
     83             }
     84         }
     85     }
     86     void work(int n,int m)
     87     {
     88         int i,j,g;
     89         memset(dp,0,sizeof(dp));
     90         dp[0][0][0] = 1;
     91         for(i = 0 ;i < n ;i++)
     92         {
     93             memset(dp[(i+1)%2],0,sizeof(dp[(i+1)%2]));
     94             for(j = 0 ;j < sz ; j++)
     95             {
     96                 for(int e = 0 ; e < (1<<m) ; e++)
     97                 {
     98                     if(!dp[i%2][j][e]) continue;
     99                     for(g = 0 ; g < child_num ; g++)
    100                     {
    101                         int o = val[ch[j][g]];
    102                         dp[(i+1)%2][ch[j][g]][e|o] = dp[i%2][j][e];
    103                     }
    104                 }
    105             }
    106         }
    107         int cnt = -INF;
    108         for(i = 0 ;i < sz ; i++)
    109         {
    110             for(j = 0 ;j < (1<<m) ; j++)
    111             {
    112                 int ans = 0;
    113                 if(!dp[n%2][i][j]) continue;
    114                 for(g = 0 ; g < m ;g++)
    115                 {
    116                     if(j&(1<<g))
    117                     ans+=v[g];
    118                 }
    119                 cnt = max(ans,cnt);
    120             }
    121         }
    122         if(cnt<0)
    123         puts("No Rabbit after 2012!");
    124         else
    125         printf("%d
    ",cnt);
    126     }
    127 }ac;
    128 int main()
    129 {
    130     int n,i,m;
    131     ac.init();
    132     while(scanf("%d%d",&m,&n)!=EOF)
    133     {
    134         ac.reset();
    135         for(i = 1;i <= m ;i++)
    136         {
    137             scanf("%s%d",vir,&v[i-1]);
    138             ac.insert(vir,i-1);
    139         }
    140         ac.construct();
    141         ac.work(n,m);
    142     }
    143     return 0;
    144 }
    View Code
  • 相关阅读:
    Java Collection知识总结
    Java异常总结
    关于触发器
    关于事务
    git分支的创建、删除、切换、合并
    github项目上传管理
    如何在github上下载单个文件夹?
    常见的javascript跨站
    各类常用端口漏洞缺陷
    SEO优化实践操作
  • 原文地址:https://www.cnblogs.com/shangyu/p/3750790.html
Copyright © 2011-2022 走看看