zoukankan      html  css  js  c++  java
  • HDU 4534 郑厂长系列故事——新闻净化

      跟 HDU 4057 Rescue the Rabbit差不多的AC自动机+dp,比赛的时候被虐成傻逼了!!!

    999的状态不多,直接状态压缩就行。dp[i][ACstatus][status] 到字符串第i位置,在AC自动机上状态为ACstatus,包含到999的状态为status。

    更新了一下自动机的模板。。。Orz简洁写法

    View Code
    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #include <vector>
    #include <cstring>
    #include <algorithm>
    #include <string>
    #include <set>
    #include <functional>
    #include <numeric>
    #include <sstream>
    #include <stack>
    #include <map>
    #include <queue>
    
    #define CL(arr, val)    memset(arr, val, sizeof(arr))
    #define REP(i, n)       for((i) = 0; (i) < (n); ++(i))
    #define FOR(i, l, h)    for((i) = (l); (i) <= (h); ++(i))
    #define FORD(i, h, l)   for((i) = (h); (i) >= (l); --(i))
    #define L(x)    (x) << 1
    #define R(x)    (x) << 1 | 1
    #define MID(l, r)   (l + r) >> 1
    #define Min(x, y)   (x) < (y) ? (x) : (y)
    #define Max(x, y)   (x) < (y) ? (y) : (x)
    #define E(x)        (1 << (x))
    #define iabs(x)     (x) < 0 ? -(x) : (x)
    #define OUT(x)  printf("%lld\n", x)
    #define Read()  freopen("data.in", "r", stdin)
    #define Write() freopen("data.out", "w", stdout);
    
    typedef long long LL;
    const double eps = 1e-6;
    const double PI = acos(-1.0);
    const int inf = 0x1F1F1F1F;
    
    using namespace std;
    
    const int N = 1610;
    
    struct node {
        int val;
        short type;
        bool cannot;
        short index;
        node *pre, *next[26];
        void init() {
            val = type = 0;
            index = cannot = 0;
            pre = NULL;
            memset(next, 0, sizeof(next));
        }
    };
    
    node trie[N];
    node *root, *q[N];
    
    int cnt, must;
    int dp[2][N][1<<8];
    int vv[2][N][1<<8];
    char str[110];
    
    void insert(node* root, char* str, int val) {
        int c, i;
        for(i = 0; str[i] != 0; ++i) {
            c = str[i] - 'a';
            if(root->next[c] == 0) {
                root->next[c] = &trie[++cnt];
                root->next[c]->init();
                root->next[c]->index = cnt;
            }
            root = root->next[c];
        }
        if(val == 999) {
            root->type |= (1<<must++);
        } else if(val == -999) {
            root->cannot = 1;
        } else {
            root->val += val;
        }
    }
    
    void buildAC() {
        int head, tail, i;
        node *u;
        root->pre = root;
    
        head = tail = 0;
        q[tail++] = root;
    
        while(head < tail) {
            u = q[head++];
    
            u->val += u->pre->val;
            u->type |= u->pre->type;
            u->cannot |= u->pre->cannot;
    
            for(i = 0; i < 26; ++i) {
                if(u->next[i] == 0) {
                    if(u == root)   u->next[i] = root;
                    else    u->next[i] = u->pre->next[i];
                } else {
                    if(u == root)   u->next[i]->pre = root;
                    else    u->next[i]->pre = u->pre->next[i];
    
                    /*
                    if(u->next[i]->pre->val)    u->next[i]->val += u->next[i]->pre->val;
                    if(u->next[i]->pre->type)   u->next[i]->type |= u->next[i]->pre->type;
                    if(u->next[i]->pre->cannot) u->next[i]->cannot = 1;
                    */
    
                    q[tail++] = u->next[i];
                }
            }
        }
    }
    
    void solve() {
        int i, j, k, c;
        int nxt, val, tt, n = strlen(str);
    
        CL(dp[1], 0x1f);
        CL(vv[1], 0);
        dp[1][0][0] = 0;
        vv[1][0][0] = 0;
    
        for(i = 0; i < n; ++i) {
            CL(dp[i&1], 0x1f);
            CL(vv[i&1], 0);
            for(j = 0; j <= cnt; ++j) {
                for(k = 0; k < (1<<must); ++k) {
    
                    if(dp[(i+1)&1][j][k] >= inf)    continue;
    
                    if(dp[i&1][j][k] > dp[(i+1)&1][j][k] + 1) {
                        dp[i&1][j][k] = dp[(i+1)&1][j][k] + 1;
                        vv[i&1][j][k] = vv[(i+1)&1][j][k];
                    } else if(dp[i&1][j][k] == dp[(i+1)&1][j][k] + 1 && vv[i&1][j][k] < vv[(i+1)&1][j][k]) {
                        vv[i&1][j][k] = vv[(i+1)&1][j][k];
                    }
    
                    c = str[i] - 'a';
                    nxt = trie[j].next[c]->index;
                    if(trie[nxt].cannot)    continue;
    
                    val = trie[nxt].val;
                    tt = k|trie[nxt].type;
    
                    if(dp[i&1][nxt][tt] > dp[(i+1)&1][j][k]) {
                        dp[i&1][nxt][tt] = dp[(i+1)&1][j][k];
                        vv[i&1][nxt][tt] = vv[(i+1)&1][j][k] + val;
                    } else if( dp[i&1][nxt][tt] == dp[(i+1)&1][j][k] &&
                         vv[i&1][nxt][tt] < vv[(i+1)&1][j][k] + val) {
                        vv[i&1][nxt][tt] = vv[(i+1)&1][j][k] + val;
                    }
                }
            }
        }
        int ans1 = inf, ans2 = 0, full = (1<<must) - 1;
        for(j = 0; j <= cnt; ++j) {
            if(ans1 > dp[(n-1)&1][j][full]) {
                ans1 = dp[(n-1)&1][j][full];
                ans2 = vv[(n-1)&1][j][full];
            }
            if(ans1 == dp[(n-1)&1][j][full] && ans2 < vv[(n-1)&1][j][full]) {
                ans2 = vv[(n-1)&1][j][full];
            }
        }
        if(ans1 == inf)     puts("Banned");
        else    printf("%d %d\n", ans1, ans2);
    }
    
    int main() {
        //freopen("data.in", "r", stdin);
    
        int T, n, g, cas = 0;
        scanf("%d", &T);
        while(T--) {
            root = &trie[0];
            root->init();
            cnt = must = 0;
            scanf("%d", &n);
            while(n--) {
                scanf("%s %d", str, &g);
                insert(root, str, g);
            }
            buildAC();
            scanf("%s", str);
            printf("Case %d: ", ++cas);
            solve();
        }
        return 0;
    }
  • 相关阅读:
    64位机配置iis 运行asp.net 程序(转载)
    病狗问题
    如何配置sqlcachedependence
    操作应用程序池
    自定义事件
    以下事情没做好决不能给客户演示
    判断用户ip是否在指定的ip段内
    silverlight4学习中解决的问题
    日历JS代码
    自己写的代码生成器ltscode2.0
  • 原文地址:https://www.cnblogs.com/vongang/p/2993593.html
Copyright © 2011-2022 走看看