zoukankan      html  css  js  c++  java
  • hdu2296Ring(ac自动机+dp)

    链接

    dp[i][j]表示长度为i在节点J的时候的权值最大值,根据trie树转移一下就行,需要每次都取最小的,所以需要另开一数组保存字典序最小的状态。

      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 1105
     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 = 26;
     19 char vir[110][15];
     20 string o[55][N];
     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[55][N];
     31     char s[N];
     32     public:
     33     void init()
     34     {
     35         fail[0] = 0;
     36         for(int i = 0 ; i < child_num ;i++)
     37         id[i+'a'] = i;
     38     }
     39     void reset()
     40     {
     41         memset(ch[0],0,sizeof(ch[0]));
     42         memset(val,0,sizeof(val));
     43         sz = 1;
     44     }
     45     void insert(char *a,int key)
     46     {
     47         int p = 0;
     48         for(; *a ; a++)
     49         {
     50             int d= id[*a];
     51             if(ch[p][d]==0)
     52             {
     53                 memset(ch[sz],0,sizeof(ch[sz]));
     54                 s[sz] = *a;
     55                 ch[p][d] = sz++;
     56             }
     57             p = ch[p][d];
     58         }
     59         val[p] = key;
     60     }
     61     void construct()
     62     {
     63         int i,head=0,tail = 0;
     64         for(i = 0; i  < child_num ;i++)
     65         {
     66             if(ch[0][i])
     67             {
     68                 fail[ch[0][i]] = 0;
     69                 Q[tail++] = ch[0][i];
     70             }
     71         }
     72         while(head!=tail)
     73         {
     74             int u = Q[head++];
     75             val[u]+=val[fail[u]];
     76             for(i = 0; i < child_num ; i++)
     77             {
     78                 if(ch[u][i])
     79                 {
     80                     fail[ch[u][i]] = ch[fail[u]][i];
     81                     Q[tail++] = ch[u][i];
     82                 }
     83                 else ch[u][i] = ch[fail[u]][i];
     84             }
     85         }
     86     }
     87     void work(int n)
     88     {
     89         int i,j,g;
     90         for(i = 0 ; i <= n ;i++)
     91             for(j = 0 ;j < sz ; j++)
     92             {
     93                 dp[i][j] = -INF;
     94                 o[i][j].clear();
     95             }
     96         dp[0][0] = 0;
     97         for(i = 0; i < n ;i++)
     98         {
     99             for(j = 0 ; j < sz ; j++)
    100             for(g = 0 ; g < child_num ; g++)
    101             {
    102                 int tv = dp[i][j]+val[ch[j][g]];
    103                 if(dp[i+1][ch[j][g]] <= tv)
    104                 {
    105                     if(dp[i+1][ch[j][g]]<tv||o[i+1][ch[j][g]]>o[i][j]+char(g+'a'))
    106                     o[i+1][ch[j][g]] = o[i][j]+char(g+'a');
    107                     dp[i+1][ch[j][g]] = dp[i][j]+val[ch[j][g]];
    108                 }
    109             }
    110         }
    111         int ans = 0,y=0,x=0;
    112         for(i = 0 ; i <=n ;i++)
    113             for(j =0 ;j < sz ; j++)
    114             {
    115                 if(ans<=dp[i][j])
    116                 {
    117                     if(ans<dp[i][j]||(y==i&&o[i][j]<o[i][x]))
    118                     {
    119                         ans = dp[i][j];
    120                         y = i;
    121                         x = j;
    122                     }
    123                 }
    124             }
    125         g = 0;
    126         if(ans==0) puts("");
    127         else
    128         cout<<o[y][x]<<endl;
    129     }
    130 }ac;
    131 int main()
    132 {
    133     int n,i,m,t;
    134     ac.init();
    135     cin>>t;
    136     while(t--)
    137     {
    138         scanf("%d%d",&n,&m);
    139         ac.reset();
    140         for(i = 1;i <= m ;i++)
    141         scanf("%s",vir[i]);
    142         for(i = 1; i <= m ;i++)
    143         {
    144             int v;
    145             scanf("%d",&v);
    146             ac.insert(vir[i],v);
    147         }
    148         ac.construct();
    149         ac.work(n);
    150     }
    151     return 0;
    152 }
    View Code
  • 相关阅读:
    《Linux内核设计与实现》读书笔记(二)- 内核开发的准备
    《Linux内核设计与实现》读书笔记(一)-内核简介
    Redis常用命令
    redis——学习之路五(简单的C#使用redis)
    Redis——学习之路四(初识主从配置)
    Redis——学习之路三(初识redis config配置)
    Redis——学习之路二(初识redis服务器命令)
    Redis——学习之路一(初识redis)
    SQL Server 查询分析器提供的所有快捷方式(快捷键)
    降维中的特征选择(转)
  • 原文地址:https://www.cnblogs.com/shangyu/p/3750774.html
Copyright © 2011-2022 走看看