Cod sursa(job #761139)

Utilizator a_h1926Heidelbacher Andrei a_h1926 Data 24 iunie 2012 22:18:54
Problema Magazin Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.4 kb
#include <cstdio>
#include <vector>
#include <algorithm>

#define NMax 30005
#define oo 1000000000

using namespace std;

vector <int> P[NMax];
int N, M, D, DD[NMax], UU[NMax], UD[NMax], DP[NMax][6], S;

void Precompute ()
{
    for (int i=0; i<N; ++i)
    {
        if (P[i].empty ())
        {
            DD[i]=UU[i]=D, UD[i]=3*D;
            continue;
        }
        DD[i]=D+2*P[i].back ();
        UU[i]=D+2*(M+1-P[i][0]);
        UD[i]=min (DD[i], UU[i])+2*D;
        for (unsigned j=0; j+1<P[i].size (); ++j)
        {
            UD[i]=min (UD[i], 2*P[i][j]+2*(M+1-P[i][j+1])+3*D);
        }
    }
    DP[0][0]=DD[0]-D, DP[0][1]=2*(M+1), DP[0][2]=min (UU[0]-D, UD[0]-3*D);
    DP[0][3]=oo, DP[0][4]=M+1, DP[0][5]=oo;
}

void Solve ()
{
    Precompute ();
    for (int i=1; i<N; ++i)
    {
        DP[i][0]=min (oo, DP[i-1][0]+DD[i]);
        DP[i][0]=min (DP[i][0], DP[i-1][1]+DD[i]);
        DP[i][0]=min (DP[i][0], DP[i-1][2]+2*(M+1)+DD[i]);
        DP[i][0]=min (DP[i][0], DP[i-1][3]+(M+1)+DD[i]);
        DP[i][0]=min (DP[i][0], DP[i-1][4]+(M+1)+DD[i]);
        DP[i][0]=min (DP[i][0], DP[i-1][5]+(M+1)+DD[i]);

        DP[i][1]=min (oo, DP[i-1][0]+D+2*(M+1));
        DP[i][1]=min (DP[i][1], DP[i-1][1]+UD[i]);
        DP[i][1]=min (DP[i][1], DP[i-1][2]+D+2*(M+1));
        DP[i][1]=min (DP[i][1], DP[i-1][3]+D+(M+1));
        DP[i][1]=min (DP[i][1], DP[i-1][4]+D+(M+1));
        DP[i][1]=min (DP[i][1], DP[i-1][5]+3*D+(M+1));

        DP[i][2]=min (oo, DP[i-1][0]+min (UU[i], UD[i]-2*D));
        DP[i][2]=min (DP[i][2], DP[i-1][1]+min (UU[i], UD[i]-2*D));
        DP[i][2]=min (DP[i][2], DP[i-1][2]+UD[i]);
        DP[i][2]=min (DP[i][2], DP[i-1][3]+min (UU[i], UD[i]-2*D)+(M+1));
        DP[i][2]=min (DP[i][2], DP[i-1][4]+min (UU[i], UD[i]-2*D)+(M+1));
        DP[i][2]=min (DP[i][2], DP[i-1][5]+min (UU[i], UD[i]-2*D)+(M+1));

        DP[i][3]=min (oo, DP[i-1][0]+(M+1)+UU[i]);
        DP[i][3]=min (DP[i][3], DP[i-1][1]+(M+1)+UU[i]);
        DP[i][3]=min (DP[i][3], DP[i-1][2]+(M+1)+UU[i]);
        DP[i][3]=min (DP[i][3], DP[i-1][3]+UU[i]);
        DP[i][3]=min (DP[i][3], DP[i-1][4]+UU[i]);
        DP[i][3]=min (DP[i][3], DP[i-1][5]+2*(M+1)+UU[i]);

        DP[i][4]=min (oo, DP[i-1][0]+D+(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]+3*D+(M+1));
        DP[i][4]=min (DP[i][4], DP[i-1][3]+D+2*(M+1));
        DP[i][4]=min (DP[i][4], DP[i-1][4]+UD[i]);
        DP[i][4]=min (DP[i][4], DP[i-1][5]+D+2*(M+1));

        DP[i][5]=min (oo, DP[i-1][0]+min (DD[i], UD[i]-2*D)+(M+1));
        DP[i][5]=min (DP[i][5], DP[i-1][1]+min (DD[i], UD[i]-2*D)+(M+1));
        DP[i][5]=min (DP[i][5], DP[i-1][2]+min (DD[i], UD[i]-2*D)+(M+1));
        DP[i][5]=min (DP[i][5], DP[i-1][3]+min (DD[i], UD[i]-2*D));
        DP[i][5]=min (DP[i][5], DP[i-1][4]+min (DD[i], UD[i]-2*D));
        DP[i][5]=min (DP[i][5], DP[i-1][5]+UD[i]);
    }
    S=min (DP[N-1][0], DP[N-1][1]);
}

void Read ()
{
    freopen ("magazin.in", "r", stdin);
    int NP; scanf ("%d %d %d %d", &NP, &N, &M, &D);
    for (; NP; --NP)
    {
        int X, Y; scanf ("%d %d", &X, &Y); --X;
        P[X].push_back (Y);
    }
    for (int i=0; i<N; ++i) sort (P[i].begin (), P[i].end ());
}

void Print ()
{
    freopen ("magazin.out", "w", stdout);
    printf ("%d\n", S);
}

int main ()
{
    Read ();
    Solve ();
    Print ();
    return 0;
}