zoukankan      html  css  js  c++  java
  • Technocup 2019 C. Compress String

    一个字符串 $s$,你要把它分成若干段,有两种合法的段

    1.段长为 $1$,代价为 $a$

    2.这个段是前面所有段拼起来组成的字符串的字串,代价为 $b$

    问最小代价

    $|s| leq 5000$

    sol:

    赛后看到带 log 的过了十分不解...

    考虑 dp

    $f_i = min(f_{i-1} + a,space min{f_j + b})$ ($s[i+1,j]$ 要在 $s[1,i]$ 中作为子串出现)

    子串的话写个 SAM 就可以线性求了,具体就是 extend 一个前缀,然后看后面能匹配几位

    #include <bits/stdc++.h>
    #define LL long long
    #define rep(i, s, t) for (register int i = (s), i##end = (t); i <= i##end; ++i)
    #define dwn(i, s, t) for (register int i = (s), i##end = (t); i >= i##end; --i)
    using namespace std;
    inline int read() {
        int x = 0, f = 1; char ch;
        for (ch = getchar(); !isdigit(ch); ch = getchar()) if (ch == '-') f = -f;
        for (; isdigit(ch); ch = getchar()) x = 10 * x + ch - '0';
        return x * f;
    }
    int n, a, b;
    int root, last, dfn;
    int tr[25010][26], fa[25010], mxlen[25010];
    char s[5010];
    int trans[5010][5010], f[5010];
    void extend(int x) {
        int p = last, np = last = ++dfn;
        mxlen[np] = mxlen[p] + 1;
        for(; !tr[p][x]; p = fa[p]) tr[p][x] = np;
        if(!p) fa[np] = root;
        else {
            int q = tr[p][x];
            if(mxlen[p] == mxlen[q] + 1) fa[np] = q;
            else {
                int nq = ++dfn; fa[nq] = fa[q];
                memcpy(tr[nq], tr[q], sizeof(tr[nq]));
                fa[q] = fa[np] = nq;
                for(; tr[p][x] == q; p = fa[p]) tr[p][x] = nq;
            }
        }
    }
    int main() {
        root = last = ++dfn;
        n = read(), a = read(), b = read();
        scanf("%s", s + 1);
        rep(i, 1 ,n) {
            extend(s[i] - 'a');
            int now = root;
            rep(j, i+1, n) {
                if(tr[now][s[j] - 'a']) trans[j][i] = 1, now = tr[now][s[j] - 'a'];
                else break;
            }
        }
        rep(i, 1, n) {
            f[i] = f[i - 1] + a;
            dwn(j, i-1, 1) if(trans[i][j]) f[i] = min(f[i], f[j] + b);
        }
        cout << f[n] << endl;
    }
    View Code
  • 相关阅读:
    github设置添加SSH
    pythonanywhere笔记
    Python3x 爬取妹子图
    python3.4 百度API接口
    简易博客开发(8)----django1.9 博客部署到pythonanywhere上
    Python3.4+Django1.9+Bootstrap3
    docker搭建私有仓库之harbor
    docker新手常见问题和知识点
    node之sinopia搭建本地npm仓库
    rancher-HA快速搭建
  • 原文地址:https://www.cnblogs.com/Kong-Ruo/p/10470916.html
Copyright © 2011-2022 走看看