Pagini recente » Cod sursa (job #3285868) | Cod sursa (job #426) | Cod sursa (job #343747) | Statisticile problemei Walle | Cod sursa (job #25536)
Cod sursa(job #25536)
#include <stdio.h>
#include <string.h>
#define NMAX 30103
#define MMAX 30
#define INF 66666666
char prod[NMAX][MMAX];
int dmin[NMAX][2][2]; // distanta minima pt a ajunge in dreptul culoarului i, 0-jos / 1-sus, cu culoarul 0-uncleared/1-cleared
int pmin[NMAX], pmax[NMAX], bestgain[NMAX], np[NMAX], sbg[NMAX];
int dq[4][NMAX], li[4], ls[4];
int i, j, k, P, N, M, D, v;
int main()
{
freopen("magazin.in", "r", stdin);
scanf("%d%d%d%d", &P, &N, &M, &D);
M++;
memset(prod, 0, sizeof(prod));
for (k = 1; k <= P; k++)
{
scanf("%d%d", &i, &j);
prod[i][j] = 1;
}
for (k = 1; k <= N; k++)
{
// proceseaza culoarul k
prod[k][0] = 1;
prod[k][M] = 1;
pmin[k] = M;
pmax[k] = 0;
for (i = 1; i < M; i++)
if (prod[k][i])
{
pmin[k] = i;
break;
}
for (i = M - 1; i >= 1; i--)
if (prod[k][i])
{
pmax[k] = i;
break;
}
np[k] = 0;
for (i = 1; i < M; i++)
if (prod[k][i])
np[k]++;
bestgain[k] = 0;
for (i = 0; i < M; i++)
if (prod[k][i])
for (j = i + 1; j <= M; j++)
if (prod[k][j])
{
if (j - i > bestgain[k])
bestgain[k] = j - i;
break;
}
}
sbg[N + 1] = 0;
for (k = N; k >= 1; k--)
sbg[k] = sbg[k + 1] + (bestgain[k]);
for (k = 1; k <= N; k++)
for (i = 0; i < 2; i++)
for (j = 0; j < 2; j++)
dmin[k][i][j] = INF;
// initialize the deques
for (i = 0; i < 4; i++)
{
dq[i][1] = INF;
li[i] = ls[i] = 1;
}
dmin[1][0][0] = 0;
for (k = 1; k <= N; k++)
{
// the deque(s) part
for (i = 0; i < 4; i++)
{
v = dq[i][li[i]];
if (i == 0)
{
v = v - 3 * D * (N - k) - (2 * M * (N - k + 1) - 2 * sbg[k]) + M;
if (v < dmin[k][1][1])
dmin[k][1][1] = v;
}
else
if (i == 1)
{
v = v - 3 * D * (N - k) - (2 * M * (N - k + 1) - 2 * sbg[k]) + M;
if (v < dmin[k][0][1])
dmin[k][0][1] = v;
}
else
if (i == 2)
{
v = v - 3 * D * (N - k) - (2 * M * (N - k) - 2 * sbg[k + 1]) + M;
if (v < dmin[k][1][1])
dmin[k][1][1] = v;
}
else
if (i == 3)
{
v = v - 3 * D * (N - k) - (2 * M * (N - k) - 2 * sbg[k + 1]) + M;
if (v < dmin[k][0][1])
dmin[k][0][1] = v;
}
}
// add values to the deque(s)
// 0
v = dmin[k][0][0] + 2 * M * (N - k + 1) - 2 * sbg[k] + 3 * D * (N - k);
while (ls[0] >= li[0] && dq[0][ls[0]] > v)
ls[0]--;
ls[0]++;
dq[0][ls[0]] = v;
// 1
v = dmin[k][1][0] + 2 * M * (N - k + 1) - 2 * sbg[k] + 3 * D * (N - k);
while (ls[1] >= li[1] && dq[1][ls[1]] > v)
ls[1]--;
ls[1]++;
dq[1][ls[1]] = v;
// 2
v = dmin[k][0][0] + 2 * M * (N - k) - 2 * sbg[k + 1] + 3 * D * (N - k);
while (ls[2] >= li[2] && dq[2][ls[2]] > v)
ls[2]--;
ls[2]++;
dq[2][ls[2]] = v;
// 3
v = dmin[k][1][0] + 2 * M * (N - k) - 2 * sbg[k + 1] + 3 * D * (N - k);
while (ls[3] >= li[3] && dq[3][ls[3]] > v)
ls[3]--;
ls[3]++;
dq[3][ls[3]] = v;
// finished deque(s)
// de jos in sus pe culoarul k
if (dmin[k][0][0] + M < dmin[k][1][1])
dmin[k][1][1] = dmin[k][0][0] + M;
if (dmin[k][0][1] + M < dmin[k][1][1])
dmin[k][1][1] = dmin[k][0][1] + M;
// de sus in jos pe culoarul k
if (dmin[k][1][0] + M < dmin[k][0][1])
dmin[k][0][1] = dmin[k][1][0] + M;
if (dmin[k][1][1] + M < dmin[k][0][1])
dmin[k][0][1] = dmin[k][1][1] + M;
// de jos, un pic in sus si inapoi jos
if (dmin[k][0][0] + 2 * pmax[k] < dmin[k][0][1])
dmin[k][0][1] = dmin[k][0][0] + 2 * pmax[k];
// de sus, un pic in jos si inapoi sus
if (dmin[k][1][0] + 2 * (M - pmin[k]) < dmin[k][1][1])
dmin[k][1][1] = dmin[k][1][0] + 2 * (M - pmin[k]);
// fa un pas pana la urmatorul culoar
if (dmin[k][0][1] + D < dmin[k + 1][0][0])
dmin[k + 1][0][0] = dmin[k][0][1] + D;
if (dmin[k][1][1] + D < dmin[k + 1][1][0])
dmin[k + 1][1][0] = dmin[k][1][1] + D;
}
freopen("magazin.out", "w", stdout);
printf("%d\n", dmin[N][0][1]);
return 0;
}