首页 > 代码库 > hdu2296Ring(ac自动机+dp)

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