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 */

 

你可能感兴趣的:(AC自动机)