zoukankan      html  css  js  c++  java
  • 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
    ",cas++);
    179         else
    180             printf("Case %d: %d %d
    ",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 */
  • 相关阅读:
    CJSon使用
    mqtt学习-3 编译运行测试
    mqtt学习-2 创建c vs项目
    mqtt学习-1 Mqtt服务器搭建
    Linux c 开发-5 使用VsCode远程调试Linux程序
    Layui数据表格之获取表格中所有的数据方法
    layui 给数据表格加序号的方法
    Layui关闭弹出层并刷新父页面,父页面向子页面传值
    MUI中小数点的数字输入框,步进step为小数时的需求和浮点数的精确问题
    MUI-numbox(数字输入框),最小值、最大值、步长、获取值、设置值、重定义
  • 原文地址:https://www.cnblogs.com/naix-x/p/3223211.html
Copyright © 2011-2022 走看看