• hdu3341Lost's revenge(ac自动机+dp)


    链接

    类似的dp省赛时就做过了,不过这题卡内存,需要把当前状态hash一下,可以按进制来算出当前的状态,因为所有的状态数是不会超过10*10*10*10的,所以完全可以把这些存下来。

    刚开始把trie的的遍历节点写在外层循环了,一直WA,后来想了一下,状态是只会向前走的,但是节点不一样,如果由 当前节点的状态-》下一节点的状态,下一节点有可能是在当前节点之前的,这样是不对的,所以需要由当前状态的节点 -》下一状态的节点 。

      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 using namespace std;
     11 #define N 510
     12 #define LL long long
     13 #define INF -1
     14 const double eps = 1e-8;
     15 const double pi = acos(-1.0);
     16 const double inf = ~0u>>2;
     17 const int child_num = 4;
     18 char vir[22],s[105];
     19 int mp[3200010];
     20 class AC
     21 {
     22     private:
     23     int ch[N][child_num];
     24     int Q[N];
     25     int fail[N];
     26     int val[N];
     27     int id[127];
     28     int sz;
     29     int dp[N][20000];
     30     public:
     31     void init()
     32     {
     33         fail[0] = 0;
     34         id['A'] = 0,id['G'] = 1,id['T'] = 2,id['C'] = 3;
     35     }
     36     void reset()
     37     {
     38         memset(ch[0],0,sizeof(ch[0]));
     39         memset(val,0,sizeof(val));
     40         sz = 1;
     41     }
     42     void insert(char *a,int key)
     43     {
     44         int p =0 ;
     45         for( ; *a ; a++)
     46         {
     47             int d = id[*a];
     48             if(ch[p][d]==0)
     49             {
     50                 memset(ch[sz],0,sizeof(ch[sz]));
     51                 ch[p][d] = sz++;
     52             }
     53             p = ch[p][d];
     54         }
     55         val[p] += key;
     56     }
     57     void construct()
     58     {
     59         int i,head=0,tail = 0;
     60         for(i = 0;i < child_num ; i++)
     61         {
     62             if(ch[0][i])
     63             {
     64                 fail[ch[0][i]] = 0;
     65                 Q[tail++] = ch[0][i];
     66             }
     67         }
     68         while(head!=tail)
     69         {
     70             int u = Q[head++];
     71             val[u]+=val[fail[u]];
     72             for(i =0 ; i < child_num ; i++)
     73             {
     74                 if(ch[u][i])
     75                 {
     76                     fail[ch[u][i]] = ch[fail[u]][i];
     77                     Q[tail++] = ch[u][i];
     78                 }
     79                 else ch[u][i] = ch[fail[u]][i];
     80             }
     81         }
     82     }
     83     void work(char *s,int kk)
     84     {
     85         int k = strlen(s);
     86         int num[5]= {0},pp[5];
     87         memset(num,0,sizeof(num));
     88         int o = 0 ,i,j,g,e,z,y;
     89         for(i = 0 ; i < k ;i++)
     90         {
     91             num[id[s[i]]]++;
     92         }
     93         pp[0] = 1;
     94         for(i = 1; i <= 4 ; i++)
     95         pp[i] = pp[i-1]*42;
     96         memset(mp,-1,sizeof(mp));
     97         for(i = 0 ; i <= num[0] ; i++)
     98             for(j = 0;j <= num[1] ; j++)
     99                 for(g =0 ; g <= num[2] ; g++)
    100                     for(e = 0 ; e <= num[3] ;e++)
    101                     {
    102                         int sum = e*pp[3]+g*pp[2]+j*42+i;
    103                         o++;
    104                         mp[sum] = o;
    105                     }
    106         memset(dp,-1,sizeof(dp));
    107         dp[0][1] = 0;
    108         for(i = 0 ; i <= num[0] ; i++)
    109             for(j = 0;j <= num[1] ; j++)
    110                 for(g = 0 ; g <= num[2] ; g++)
    111                     for(e = 0 ; e <= num[3] ;e++)
    112                     {
    113                         for(z = 0  ;z < sz ; z++)
    114                         {
    115                             int sum = e*pp[3]+g*pp[2]+j*42+i;
    116                             if(dp[z][mp[sum]]==-1) continue;
    117                             for(y = 0; y < child_num ; y++)
    118                             {
    119                                 int yy = ch[z][y];
    120                                 int ss = pp[y]+sum;
    121                                 if(mp[ss]==-1) continue;
    122                                 dp[yy][mp[ss]] = max(dp[yy][mp[ss]],dp[z][mp[sum]]+val[yy]);
    123                             }
    124                         }
    125                     }
    126         int ans = 0;
    127         for(i = 0;i < sz ; i++)
    128         {
    129             ans=max(dp[i][o],ans);
    130         }
    131         printf("Case %d: ",kk);
    132         printf("%d
    ",ans);
    133     }
    134 }ac;
    135 int main()
    136 {
    137     int n,kk=0;
    138     ac.init();
    139     while(scanf("%d",&n)&&n)
    140     {
    141         ac.reset();
    142         kk++;
    143         while(n--)
    144         {
    145             scanf("%s",vir);
    146             ac.insert(vir,1);
    147         }
    148         ac.construct();
    149         scanf("%s",s);
    150         ac.work(s,kk);
    151     }
    152     return 0;
    153 }
    View Code
  • 相关阅读:
    懒加载
    通过Xib自定义控件
    自定义控件
    swiper_banner图的封装
    uni-app中封装的search和scroll-view
    使用git从创建仓库或项目到push到远程并创建分支常用命令
    随手封装一个简单的日期组件(基于ele-ui的基础上)
    封装的一个时间条插件
    websocket的封装2
    websocket的封装1(做vue中的通信经常也是大概率用到的)
  • 原文地址:https://www.cnblogs.com/shangyu/p/3750810.html
Copyright © 2020-2023  润新知