Anonymous 2020 CCPC Wannafly Winter Camp Day2-K- breaking of Intuit head

Topic Portal

sol: first built by AC dictionary automatic mechanism, with $ dp [i] $ denotes the minimum cost string length $ i $ front position, if a word string length $ s $ is a front $ i $ suffix entries, it can be with $ dp [i - len (s )] + val (s) $ proceeds to $ dp [i] $.

  • AC automaton
    #include <bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    typedef pair<int, int> PII;
    const int MAXN = 500010;
    const LL INF = 0x3f3f3f3f3f3f3f3f;
    struct Trie {
        int son[MAXN][26], fail[MAXN], last[MAXN], dep[MAXN];
        LL val[MAXN], dp[MAXN]; int tot, root;
        int add_node(int d) {
            memset(son[tot], -1, sizeof(son[tot]));
            dep[tot] = d; val[tot] = INF;
            return tot ++;
        }
        void init() {
            memset(dp, INF, sizeof(dp));
            dp[0] = tot = 0;
            root = add_node(0);
        }
        void insert(char* s, LL v) {
            int p = root;
            for (int i = 0; s[i]; i++) {
                int index = s[i] - 'a';
                if (son[p][index] == -1)
                    son[p][index] = add_node(i + 1);
                p = son[p][index];
            }
            val[p] = min(val[p], v);
        }
        void build() {
            queue<int> que; fail[root] = root;
            for (int i = 0; i < 26; i++) {
                if (son[root][i] == -1) son[root][i] = root;
                else {
                    fail[son[root][i]] = root;
                    last[son[root][i]] = root;
                    que.push(son[root][i]);
                }
            }
            while (!que.empty()) {
                int p = que.front(); que.pop();
                for (int i = 0; i < 26; i++) {
                    if (son[p][i] == -1) son[p][i] = son[fail[p]][i];
                    else {
                        fail[son[p][i]] = son[fail[p]][i];
                        if (val[son[fail[p]][i]] != INF)
                            last[son[p][i]] = son[fail[p]][i];
                        else
                            last[son[p][i]] = son[last[p]][i];
                        que.push(son[p][i]);
                    }
                }
            }
        }
        LL slove(char* s) {
            int p = root, len = strlen(s);
            for (int i = 0; i < len; i++) {
                int index = s[i] - 'a';
                p = son[p][index];
                for (int tmp = p; tmp != root; tmp = last[tmp])
                    dp[i + 1] = min(dp[i + 1], dp[i + 1 - dep[tmp]] + val[tmp]);
            }
            if (dp[len] == INF) return -1;
            else return dp[len];
        }
    } ac;
    char s[MAXN];
    int main() {
        int n, v;
        scanf("%d", &n); ac.init();
        for (int i = 1; i <= n; i++) {
            scanf("%s%d", s, &v);
            ac.insert(s, v);
        }
        ac.build();
        scanf("%s", s);
        printf("%lld\n", ac.slove(s));
        return 0;
    }

    AC automaton unskilled, hate the hard knocks out three days, it has been timed out. I have learned to optimize two AC automaton.

Guess you like

Origin www.cnblogs.com/Angel-Demon/p/12230472.html