#include <iostream>
#include <vector>
#include <algorithm>
#include <cassert>
#include <map>
#include <random>
using ll = long long;
#define debug(x) #x << " = " << x << '\n'
const ll INF = 1e18;
std::mt19937 rng(123);
std::map<int, std::vector<int>> where;
struct stringHash {
std::vector<int> pref;
std::vector<int> value;
std::vector<int> p;
const int mod = 1e9 + 123;
const int B = 37;
int n;
void init(std::string s) {
n = (int) s.size();
pref.resize(n + 1, 0);
p.resize(n + 1);
p[0] = 1;
for (int i = 1; i <= n; i++) {
p[i] = (ll) p[i - 1] * B % mod;
}
value.resize(256);
for (int &x : value) {
x = rng() % mod;
}
for (int i = 1; i <= n; i++) {
pref[i] = pref[i - 1] + (ll) value[s[i]] * p[i] % mod;
pref[i] %= mod;
}
}
int queryHash(int l, int r) {
int ret = pref[r] - pref[l - 1];
if (ret < 0) {
ret += mod;
}
// teoretic trebuie sa inmultesc cu B^-l (devastator)
// dar o sa inmultesc cu B^(n-l) (asta e mega smart)
return (ll) ret * p[n - l] % mod;
}
};
signed main() {
std::ios_base::sync_with_stdio(false);
std::cin.tie(0);
int n;
std::cin >> n;
std::string s;
std::cin >> s;
s = '$' + s;
int A, B, C;
std::cin >> A >> B >> C;
std::vector<std::vector<ll>> dp(n + 2, std::vector<ll>(n + 2, +INF));
for (int i = 1; i <= n; i++) {
dp[i][i - 1] = 0;
dp[i][i] = A;
}
stringHash hash1;
hash1.init(s);
for (int len = 1; len <= n; len++) {
std::vector<int> next(n + 1, -1);
for (int i = 1; i + len - 1 <= n; i++) {
// where[hash1.queryHash(i, i + len - 1)].push_back(i);
}
for (int i = 1; i + len - 1 <= n; i++) {
int j = i + len;
while (j + len - 1 <= n && hash1.queryHash(i, i + len - 1) != hash1.queryHash(j, j + len - 1)) {
j++;
}
if (j + len - 1 <= n) {
next[i] = j;
} else {
next[i] = -1;
}
}
for (int i = 1; i + len - 1 <= n; i++) {
dp[i][i + len - 1] = std::min(dp[i][i + len - 1], std::min(dp[i][i + len - 2], dp[i + 1][i + len - 1]) + A);
}
for (int i = 1; i + len - 1 <= n; i++) {
if (next[i] != -1) {
int j = i;
int cnt = 0; // de cate ori dau paste
while (next[j] != -1) {
j = next[j];
cnt++;
dp[i][j + len - 1] = std::min(dp[i][j + len - 1], B + dp[i][i + len - 1] + (ll) (cnt + 1) * C + (ll) (j - i - cnt * len) * A);
}
}
}
}
std::cout << dp[1][n];
return 0;
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |