제출 #1338058

#제출 시각아이디문제언어결과실행 시간메모리
1338058MisterReaperCopy and Paste 3 (JOI22_copypaste3)C++20
100 / 100
143 ms74176 KiB
#include <bits/stdc++.h>

using i64 = long long;

#ifdef DEBUG
    #include "debug.h"
#else
    #define debug(...) void(23)
#endif

constexpr i64 inf = i64(1E18);
constexpr int max_N = 2500 + 5;

i64 f[max_N][max_N];

bool chmin(i64& a, i64 b) {
    if (a > b) {
        a = b;
        return true;
    }
    return false;
}

int nxt[max_N][max_N];

inline std::vector<int> Z(std::string s) {
    int n = int(s.size());
    std::vector<int> z(n);
    for (int i = 1, j = 0; i < n; ++i) {
        z[i] = std::max(0, std::min(j + z[j] - i, z[i - j]));
        while (i + z[i] < n && s[z[i]] == s[i + z[i]]) {
            z[i]++;
        }
        if (i + z[i] > j + z[j]) {
            j = i;
        }
        #ifdef LOCAL
            assert(s.substr(0, z[i]) == s.substr(i, z[i]));
        #endif
    }

    return z;
}

int main() {
    std::ios_base::sync_with_stdio(false);
    std::cin.tie(nullptr);

    std::fill_n(&f[0][0], max_N * max_N, inf);

    std::fill_n(&nxt[0][0], max_N * max_N, max_N);

    int N;
    std::cin >> N;
    std::string S;
    std::cin >> S;
    i64 A, B, C;
    std::cin >> A >> B >> C;

    auto g = [&](int l, int r) -> i64 {
        return A * (r - l + 1);
    };

    for (int i = 0; i < N; ++i) {
        std::string t = S.substr(i);
        std::vector<int> z = Z(t);
        int n = int(t.size()), p = 0;
        for (int j = 0; j < n; ++j) {
            for (int k = p; k < std::min(z[j], j); ++k) {
                nxt[k + 1][i] = i + j;
                ++p;
            }
        }
    }

    #ifdef DEBUG
        for (int i = 0; i < N; ++i) {
            for (int k = 1; k <= N; ++k) {
                std::cerr << nxt[k][i] << " \n"[k == N];
            }
        }
    #endif

    for (int i = 0; i < N; ++i) {
        for (int j = 0; j < i; ++j) {
            f[i][j] = 0;
        }
    }

    for (int i = 0; i < N; ++i) {
        f[i][i] = A;
    }

    for (int s = 0; s < N; ++s) {
        for (int l = 0; l + s < N; ++l) {
            int r = l + s;
            if (l != r) {
                chmin(f[l][r], f[l][r - 1] + A);
                chmin(f[l][r], f[l + 1][r] + A);
            }
            int k = r - l + 1;
            i64 now = f[l][l + k - 1] + B + C;
            int rs = l;
            debug(l, r, nxt[k][rs]);
            while (nxt[k][rs] + k - 1 < N) {
                int p = nxt[k][rs];
                debug(p);
                assert(rs + k <= p);
                now += g(rs + k, p - 1) + C;
                debug(l, p + k - 1, now);
                chmin(f[l][p + k - 1], now);
                rs = p;
            }
        }
    }

    #ifdef DEBUG
        for (int i = 0; i < N; ++i) {
            for (int j = i; j < N; ++j) {
                debug(i, j, f[i][j]);
            }
        }
    #endif

    i64 ans = f[0][N - 1];
    std::cout << ans << '\n';

    return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...