Cod sursa(job #1878250)

Utilizator alex_HarryBabalau Alexandru alex_Harry Data 13 februarie 2017 23:05:44
Problema Magazin Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.34 kb
#include <fstream>
#include <algorithm>
using namespace std;
ifstream f("magazin.in");
ofstream g("magazin.out");
const int NMax = 50005;
int P, N, M, D;
vector <int> V[NMax];
int DP[NMax][8];
int Part[NMax], Part2[NMax];
void Read()
{
    f >> P >> N >> M >> D;
    for(int i = 1; i <= P; i++)
    {
        int x, y;
        f >> x >> y;
        V[x].push_back(y);
    }
    for(int i = 1; i <= N; i++)
        sort(V[i].begin(), V[i].end());
}

void precalcNumber()
{
    for(int i = 1; i <= N; i++)
    {
        if(V[i].size() == 0)
        {
            Part[i] = 3 * D;
            continue;
        }

        int Min = 0x3f3f3f3f, Min2 = 0x3f3f3f3f;
        for(int j = 0; j < V[i].size() - 1; j++)
        {
            if(Min > V[i][j] * 2 + (M - V[i][j + 1] + 1) * 2)
                Min = V[i][j] * 2 + (M - V[i][j + 1] + 1) * 2;
        }
        Min = min(Min, V[i].back() * 2);
        Min = min(Min, (M - V[i].front() + 1) * 2);
        Part[i] = Min + 3 * D;
    }
}
int min(int a, int b)
{
    if(a > b)
        return b;
    return a;
}
void Solve()
{
    for(int i = 1; i <= N; i++)
        for(int j = 0; j < 6; j++)
            DP[i][j] = 0x3f3f3f3f;
    if(V[1].size() > 0)
        DP[1][0] = V[1].back() * 2;
    else
        DP[1][0] = 0;
    DP[1][1] = M + 1;
    DP[1][2] = Part[1] - D;
    DP[1][3] = M + 1;
    DP[1][4] = M + 1 + M + 1;
    //DP[1][5] = Part[1];
    for(int i = 2; i <= N; i++)
    {
        int a, b;
        if(V[i].size() == 0)
            a = b = 0;
        else
        {
            a = V[i].back() * 2;
            b = (M - V[i].front() + 1) * 2;
        }
        DP[i][0] = min(DP[i][0], DP[i - 1][0] + D + a);
        DP[i][0] = min(DP[i][0], DP[i - 1][1] + M + 1 + D + a);
        //DP[i][0] = min(DP[i][0], DP[i - 1][2] + D + a);
        DP[i][0] = min(DP[i][0], DP[i - 1][3] + M + 1 + D + a);
        DP[i][0] = min(DP[i][0], DP[i - 1][4] + D + a);
        DP[i][1] = min(DP[i][1], DP[i - 1][1] + Part[i]);
        DP[i][4] = min(DP[i][4], DP[i - 1][4] + Part[i]);
        /*DP[i][0] = min(DP[i][0], DP[i - 1][1] + M + 1 + Part[i]);*/
        //DP[i][3] = min(DP[i][3], DP[i - 1][4] + M + 1 + Part[i]);
        //DP[i][0] = min(DP[i][0], DP[i - 1][5] + )
        DP[i][1] = min(DP[i][1], DP[i - 1][0] + D + M + 1);
        DP[i][1] = min(DP[i][1], DP[i - 1][1] + M + 1 + M + 1 + D);
        DP[i][1] = min(DP[i][1], DP[i - 1][2] + D + M + 1);
        DP[i][1] = min(DP[i][1], DP[i - 1][3] + D + M + 1 + M + 1);
        DP[i][1] = min(DP[i][1], DP[i - 1][4] + D + M + 1);
        DP[i][2] = min(DP[i][2], DP[i - 1][0] + Part[i]);
        DP[i][2] = min(DP[i][2], DP[i - 1][1] + M + 1 + Part[i]);
        DP[i][2] = min(DP[i][2], DP[i - 1][2] + Part[i]);
        DP[i][2] = min(DP[i][2], DP[i - 1][4] + Part[i]);
        DP[i][2] = min(DP[i][2], M + 1 + Part[i] + DP[i - 1][3]);
        DP[i][3] = min(DP[i][3], DP[i - 1][1] + b + D);
        DP[i][3] = min(DP[i][3], DP[i - 1][3] + D + b);
        DP[i][3] = min(DP[i][3], DP[i - 1][4] + M + 1 + D + b);
        DP[i][3] = min(DP[i][3], DP[i - 1][0] + M + 1 + D + b);
        //DP[i][3] = min(DP[i][3], DP[i - 1][5] + D + b);
        DP[i][4] = min(DP[i][4], DP[i - 1][0] + D + M + 1 + M + 1);
        DP[i][4] = min(DP[i][4], DP[i - 1][1] + D + M + 1);
        //DP[i][4] = min(DP[i][4], DP[i - 1][2] + D + M + 1 + M + 1);
        DP[i][4] = min(DP[i][4], DP[i - 1][3] + D + M + 1);
        DP[i][4] = min(DP[i][4], DP[i - 1][4] + M + 1 + D + M + 1);
        DP[i][4] = min(DP[i][4], DP[i - 1][5] + D + M + 1);
        DP[i][5] = min(DP[i][5], DP[i - 1][3] + Part[i]);
        DP[i][5] = min(DP[i][5], DP[i - 1][4] + M + 1 + Part[i]);
        DP[i][5] = min(DP[i][5], DP[i - 1][5] + Part[i]);
        DP[i][5] = min(DP[i][5], DP[i - 1][0] + M + 1 + Part[i]);
        DP[i][5] = min(DP[i][5], DP[i - 1][1] + Part[i]);
        DP[i][1] = min(DP[i][1], DP[i - 1][5] + 2 * M + D + 2);
        DP[i][4] = min(DP[i][4], DP[i - 1][2] + 2 * M + D + 2);
        DP[i][0] = min(DP[i][0], DP[i][4]);
        DP[i][3] = min(DP[i][3], DP[i][1]);
    }
    int Min = 0x3f3f3f3f;
    Min = min(Min, DP[N][0]);
    Min = min(Min, DP[N][4]);
    /*Min = min(Min, DP[N][1] + M + 1);
    Min = min(Min, DP[N][3] + M + 1);*/
    g << Min << "\n";
}
int main()
{
    Read();
    precalcNumber();
    Solve();
    return 0;
}