Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- using namespace std;
- #define x first
- #define y second
- #define pb push_back
- #define mp make_pair
- #define sqr(a) ((a) * (a))
- #define sz(a) int((a).size())
- #define all(a) (a).begin(), (a).end()
- #define forn(i, n) for (int i = 0; i < int(n); ++i)
- #define fore(i, l, r) for (int i = int(l); i < int(r); ++i)
- template<class A, class B> ostream& operator << (ostream& out, const pair<A, B> &a) {
- return out << "(" << a.x << ", " << a.y << ")";
- }
- template<class A> ostream& operator << (ostream& out, const vector<A> &a) {
- out << "[";
- for (auto it = a.begin(); it != a.end(); ++it) {
- if (it != a.begin())
- out << ", ";
- out << *it;
- }
- return out << "]";
- }
- typedef long long li;
- typedef long double ld;
- typedef pair<int, int> pt;
- mt19937 rnd(time(NULL));
- mt19937_64 rnd64(time(NULL));
- const int INF = 1e9;
- const li INF64 = 1e18;
- const int MOD = 1e9 + 7;
- const ld PI = acosl(-1.0);
- const ld EPS = 1e-9;
- const int N = 5010;
- int n, X, Y, Z;
- int a[N];
- bool read() {
- if (scanf("%d%d%d%d", &n, &X, &Y, &Z) != 4)
- return false;
- forn(i, n) scanf("%d", &a[i]);
- return true;
- }
- li dp[N][N];
- int nxt[N][N], prv[N][N];
- vector<int> z_function(const vector<int>& s) {
- int n = sz(s);
- vector<int> z(n);
- for (int i = 1, l = 0, r = 0; i < n; ++i) {
- if (i <= r)
- z[i] = min (r - i + 1, z[i - l]);
- while (i + z[i] < n && s[z[i]] == s[i + z[i]])
- ++z[i];
- if (i + z[i] - 1 > r)
- l = i, r = i + z[i] - 1;
- }
- return z;
- }
- void solve() {
- forn(i, n + 1) fore(j, 0, n + 1) {
- prv[i][j] = 0;
- nxt[i][j] = -1;
- }
- forn(i, n) {
- vector<int> s(n - i);
- fore(j, i, n) s[j - i] = a[j];
- auto z = z_function(s);
- int pos = 1;
- fore(j, 1, sz(s)) {
- pos = max(pos, j);
- while (pos < sz(s) && z[pos] < j)
- pos++;
- if (pos < sz(s)) {
- nxt[i + j][j] = pos + i + j;
- }
- }
- }
- reverse(a, a + n);
- forn(i, n) {
- vector<int> s(n - i);
- fore(j, i, n) s[j - i] = a[j];
- auto z = z_function(s);
- int pos = 1;
- fore(j, 1, sz(s)) {
- pos = max(pos, j);
- while (pos < sz(s) && z[pos] < j)
- pos++;
- if (pos < sz(s)) {
- int pp = n - (i + j);
- prv[pp][j] = 1;
- //cout << pp << " " << j << endl;
- }
- }
- }
- reverse(a, a + n);
- //forn(i, n) forn(j, n) {
- // cout << i << " " << j << " " << nxt[i][j] << endl;
- //}
- forn(i, n + 1) forn(j, n + 1)
- dp[i][j] = INF64;
- dp[0][0] = 0;
- forn(i, n) {
- li mn = INF64;
- forn(j, i + 1) if (dp[i][j] != INF64) {
- //cout << i << " " << j << " " << dp[i][j] << endl;
- mn = min(mn, dp[i][j]);
- dp[i + 1][0] = min(dp[i + 1][0], dp[i][j] + X);
- if (j != 0 && nxt[i][j] != -1) {
- dp[nxt[i][j]][j] = min(dp[nxt[i][j]][j], dp[i][j] + Z + li(nxt[i][j] - i - j) * X);
- }
- }
- fore(k, 1, i + 1) {
- if (prv[i][k]) {
- dp[i + k][k] = min(dp[i + k][k], mn + Y + Z);
- }
- }
- }
- li ans = INF64;
- forn(i, n + 1) ans = min(ans, dp[n][i]);
- printf("%lld\n", ans);
- }
- int main() {
- #ifdef _DEBUG
- freopen("input.txt", "r", stdin);
- //freopen("output.txt", "w", stdout);
- int tt = clock();
- #endif
- cout << fixed << setprecision(10);
- cerr << fixed << setprecision(10);
- int tc;
- scanf("%d", &tc);
- forn(i, tc) {
- read();
- printf("Case #%d: ", i + 1);
- solve();
- #ifdef _DEBUG
- cerr << "TIME = " << clock() - tt << endl;
- tt = clock();
- #endif
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement