Cod sursa(job #2636062)

Utilizator giotoPopescu Ioan gioto Data 16 iulie 2020 14:11:46
Problema Magazin Scor 15
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.29 kb
#include <bits/stdc++.h>
using namespace std;

const int DIM = 3e4 + 5;
const int INF = 1e9;

int p, n, m, d;
int st[DIM], dr[DIM];
int dp[DIM][2][3];

int main()
{
    freopen("magazin.in", "r", stdin);
    freopen("magazin.out", "w", stdout);

    scanf("%d%d%d%d", &p, &n, &m, &d);

    int x, y;
    for (int i = 1; i <= p ; ++i) {
        scanf("%d%d", &x, &y);
        if (st[x]) {
            st[x] = min(st[x], y);
            dr[x] = max(dr[x], y);
        }
        else st[x] = dr[x] = y;
    }

    for (int j = 0; j <= 1 ; ++j)
        for (int k = 0; k <= 2 ; ++k)
            dp[0][j][k] = INF;

    dp[0][0][0] = 0;

    ++m;
    for (int i = 1; i <= n ; ++i) {
        if (!st[i]) {
            for (int j = 0; j <= 1 ; ++j)
                for (int k = 0; k <= 1 ; ++k)
                    dp[i][j][k] = dp[i - 1][j][k] + d + 2 * (k != 0) * d;
            continue ;
        }

        ++st[i];
        ++dr[i];
        ///tranzitiile normale
        dp[i][0][0] = dp[i - 1][0][0] + dr[i] * 2 + d;
        for (int k = 1; k <= 2 ; ++k)
        dp[i][0][k] = dp[i - 1][0][k] + dr[i] * 2 + 3 * d;

        dp[i][1][0] = dp[i - 1][1][0] + (m - st[i] + 1) * 2 + d;
        for (int k = 1; k <= 2 ; ++k)
        dp[i][1][k] = dp[i - 1][1][k] + (m - st[i] + 1) * 2 + 3 * d;

        ///tranzitie in care schimb partea
        for (int k = 0; k <= 1 ; ++k)
            dp[i][k][0] = min(dp[i][k][0], min(dp[i - 1][1 - k][0], dp[i - 1][1 - k][1] + 2 * d) + m + d);

        dp[i][0][0] = min(dp[i][0][0], dp[i - 1][0][2] + m + 3 * d + 2 * dr[i]);
        dp[i][1][0] = min(dp[i][1][0], dp[i - 1][1][2] + m + 3 * d + 2 * (m - st[i] + 1));

        ///tranzitie in care ignor culoarul
        dp[i][0][1] = min(dp[i][0][1], min(dp[i - 1][0][0], dp[i - 1][0][1] + 2 * d) + d + 2 * (m - st[i] + 1));
        dp[i][1][1] = min(dp[i][1][1], min(dp[i - 1][1][0], dp[i - 1][1][1] + 2 * d) + d + 2 * dr[i]);

        dp[i][0][2] = min(dp[i][0][2], dp[i - 1][0][0] + d);
        dp[i][1][2] = min(dp[i][1][2], dp[i - 1][1][0] + d);

        ///schimb partea pe loc
        for (int k = 0; k <= 1 ; ++k)
            dp[i][k][0] = min(dp[i][k][0], min(dp[i][1 - k][0], min(dp[i][1 - k][1], dp[i][1 - k][2])) + m);
    }

    printf("%d", dp[n][0][0] - d);

    return 0;
}