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
  • 相关阅读:
    LeetCode对撞指针汇总
    167. Two Sum II
    215. Kth Largest Element in an Array
    2018Action Recognition from Skeleton Data via Analogical Generalization over Qualitative Representations
    题解 Educational Codeforces Round 84 (Rated for Div. 2) (CF1327)
    题解 JZPKIL
    题解 八省联考2018 / 九省联考2018
    题解 六省联考2017
    题解 Codeforces Round #621 (Div. 1 + Div. 2) (CF1307)
    题解Codeforces Round #620 (Div. 2)
  • 原文地址:https://www.cnblogs.com/shangyu/p/3750790.html
Copyright © 2011-2022 走看看