HDU 4534 郑厂长系列故事——新闻净化(AC自动机+DP)

题目链接

蛋碎了,开始理解错题意的,以为跟上个题一样要替换。。。然后发现删除我不会啊,然后听宝哥讲了讲转移过程后,也不算难理解,主要是被前面的题给局限住思维了。

然后就是漫长的debug过程,手动构造数据,构造的我心碎了,最后看别人代码才发现错误,别人的代码实现方式和我明显不是一个风格的,我看的也很纠结啊。。。

在AC自动机构造关系的时候,开始只注意了-999的转移,然后慢慢debug后+上权值的转移,最后才发现999串的转移也要有,折腾了一天,终于过了。

  1 #include <iostream>
  2 #include <cstring>
  3 #include <cstdio>
  4 #include <queue>
  5 #include <algorithm>
  6 #include <cstdlib>
  7 using namespace std;
  8 #define N 2000
  9 #define INF 10000000
 10 int t;
 11 int trie[N][26];
 12 int o[N];
 13 int que[N];
 14 int flag[N];
 15 int fail[N];
 16 int wa[N];
 17 int dp1[N][256];
 18 int dp2[N][256];
 19 int goal1[N][256];
 20 int goal2[N][256];
 21 int num;
 22 void CL()
 23 {
 24     num = 0;
 25     memset(trie,-1,sizeof(trie));
 26     memset(o,0,sizeof(o));
 27     memset(flag,0,sizeof(flag));
 28     memset(wa,0,sizeof(flag));
 29     t = 1;
 30 }
 31 void insert(char *str,int x)
 32 {
 33     int i,root,len,sum;
 34     root = 0;
 35     len = strlen(str);
 36     sum = 0;
 37     for(i = 0; i < len; i ++)
 38     {
 39         if(trie[root][str[i]-'a'] == -1)
 40             trie[root][str[i]-'a'] = t ++;
 41         root = trie[root][str[i]-'a'];
 42     }
 43     if(x == 999)
 44     {
 45         flag[root] = 1<<num;
 46         num ++;
 47     }
 48     else if(x == -999)
 49     {
 50         wa[root] = 1;
 51     }
 52     else
 53         o[root] += x;
 54 }
 55 void build_ac()
 56 {
 57     int head,tail,front,i;
 58     head = tail = 0;
 59     for(i = 0; i < 26; i ++)
 60     {
 61         if(trie[0][i] != -1)
 62         {
 63             fail[trie[0][i]] = 0;
 64             que[tail++] = trie[0][i];
 65         }
 66         else
 67         {
 68             trie[0][i] = 0;
 69         }
 70     }
 71     while(head != tail)
 72     {
 73         front = que[head++];
 74         flag[front] |= flag[fail[front]];
 75         wa[front] |= wa[fail[front]];
 76         o[front] += o[fail[front]];
 77         for(i = 0; i < 26; i ++)
 78         {
 79             if(trie[front][i] != -1)
 80             {
 81                 que[tail++] = trie[front][i];
 82                 fail[trie[front][i]] = trie[fail[front]][i];
 83             }
 84             else
 85             {
 86                 trie[front][i] = trie[fail[front]][i];
 87             }
 88         }
 89     }
 90 }
 91 int main()
 92 {
 93     int cas = 1,i,j,k,n,len,x,d;
 94     char str[101];
 95     scanf("%d",&d);
 96     while(d--)
 97     {
 98         scanf("%d",&n);
 99         CL();
100         for(i = 1; i <= n; i ++)
101         {
102             scanf("%s%d",str,&x);
103             insert(str,x);
104         }
105         build_ac();
106         scanf("%s",str);
107         len = strlen(str);
108         for(i = 0; i <= t; i ++)
109         {
110             for(j = 0; j < (1<<num); j ++)
111             {
112                 dp1[i][j] = INF;
113                 dp2[i][j] = INF;
114                 goal1[i][j] = -INF;
115                 goal2[i][j] = -INF;
116             }
117         }
118         dp1[0][0] = 0;
119         goal1[0][0] = 0;
120         for(i = 0; i < len; i ++)
121         {
122             for(j = 0; j < t; j ++)
123             {
124                 if(wa[j]) continue;
125                 for(k = 0; k < (1<<num); k ++)
126                 {
127                     if(dp1[j][k] == INF) continue;
128                     if(dp2[j][k] > dp1[j][k] + 1)
129                     {
130                         dp2[j][k] = dp1[j][k] + 1;
131                         goal2[j][k] = goal1[j][k];
132                     }
133                     else if(dp2[j][k] == dp1[j][k] + 1)
134                     {
135                         goal2[j][k] = max(goal2[j][k],goal1[j][k]);
136                     }
137                     int c = str[i] - 'a';
138                     if(wa[trie[j][c]]) continue;
139                     int temp,val;
140                     temp = k|flag[trie[j][c]];
141                     val = o[trie[j][c]];
142                     if(dp2[trie[j][c]][temp] > dp1[j][k])
143                     {
144                         dp2[trie[j][c]][temp] = dp1[j][k];
145                         goal2[trie[j][c]][temp] = goal1[j][k] + val;
146                     }
147                     else if(dp2[trie[j][c]][temp] == dp1[j][k])
148                     {
149                         goal2[trie[j][c]][temp] = max(goal2[trie[j][c]][temp],goal1[j][k] + val);
150                     }
151                 }
152             }
153             for(j = 0; j <= t; j ++)
154             {
155                 for(k = 0; k < (1<<num); k ++)
156                 {
157                     dp1[j][k] = dp2[j][k];
158                     dp2[j][k] = INF;
159                     goal1[j][k] = goal2[j][k];
160                     goal2[j][k] = -INF;
161                 }
162             }
163         }
164         int ans1 = INF,ans2 = -INF;
165         for(i = 0; i < t; i ++)
166         {
167             if(ans1 > dp1[i][(1<<num)-1])
168             {
169                 ans1 = dp1[i][(1<<num)-1];
170                 ans2 = goal1[i][(1<<num)-1];
171             }
172             else if(ans1 == dp1[i][(1<<num)-1]&&ans2 < goal1[i][(1<<num)-1])
173             {
174                 ans2 = goal1[i][(1<<num)-1];
175             }
176         }
177         if(ans1 >= INF)
178             printf("Case %d: Banned\n",cas++);
179         else
180             printf("Case %d: %d %d\n",cas++,ans1,ans2);
181     }
182     return 0;
183 }
184 /*
185 9
186 3
187 abdc 2
188 bd 3
189 c 4
190 abdc
191 3
192 aba 999
193 a 6
194 ab 5
195 aba
196 3
197 3
198 ab -1
199 bc -2
200 d -3
201 abcd
202 */

 

转载于:https://www.cnblogs.com/naix-x/p/3223211.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值