Cod sursa(job #164299)

Utilizator vlad.maneaVlad Manea vlad.manea Data 23 martie 2008 21:01:46
Problema Wanted Scor 10
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.97 kb
#include <stdio.h>
#define nmax 205
#define infinit 2000000000

int X[nmax], Y[nmax], Z[nmax], T[nmax];

int N, ans;

int D[nmax][nmax], S[nmax][nmax], d[nmax][nmax];

void msort(int l, int r)
{
	if (l >= r)
		return;

	int m = (l+r)>>1, i, j, k;

	msort(l, m);
	msort(m+1, r);

	for (i = k = l, j = m+1; i <= m && j <= r; k++)
	{
		if (X[i] <= X[j])
		{
			Z[k] = X[i];
			T[k] = Y[i];
			i++;
		}
		else
		{
			Z[k] = X[j];
			T[k] = Y[j];
			j++;
		}
	}

	for (; i <= m; i++, k++)
	{
		Z[k] = X[i];
		T[k] = Y[i];
	}

	for (; j <= r; j++, k++)
	{
		Z[k] = X[j];
		T[k] = Y[j];
	}

	for (k = l; k <= r; ++k)
	{
		X[k] = Z[k];
		Y[k] = T[k];
	}
}

void read()
{
	int i;

	freopen("wanted.in", "r", stdin);

	scanf("%d", &N);

	for (i = 1; i <= N; ++i)
		scanf("%d%d", &X[i], &Y[i]);
}

int max(int l, int r)
{
	return l < r? r: l;
}

void solve()
{
	int i, l, j, k, x;

	// sortez orasele dupa coordonata x
	msort(1, N);

	// distanta dintre doua orase, parcurse
	for (i = 1; i <= N; ++i)
		for (j = i+1; j <= N; ++j)
			d[i][j] = d[j][i] = Y[i] + Y[j] + (X[i] > X[j]? X[i]-X[j]: X[j]-X[i]);

	// dreptele de lungime 1
	for (i = 1; i < N; ++i)
		D[i][i+1] = d[i][i+1];

	for (i = 2; i <= N; ++i)
		S[i][i-1] = d[i][i-1];

	for (l = 2; l <= N; ++l)
	{
		// la stanga
		for (i = l+1; i <= N; ++i)
			for (S[i][i-l] = infinit, k = 1; k < i; ++k)
				if ((x = d[i][k] + max(S[k][i-l], D[k][i-1])) < S[i][i-l])
					S[i][i-l] = x;

		// la dreapta
		for (i = 1; i <= N-l+1; ++i)
			for (D[i][i+l-1] = infinit, k = i+1; k <= N; ++k)
				if ((x = d[i][k] + max(S[k][i+1], D[k][i+l-1])) < D[i][i+l-1])
					D[i][i+l-1] = x;
	}

	ans = infinit;
	for (i = 1; i <= N; ++i)
		if ((x = max(S[i][1], D[i][N]) + Y[i] + (X[i] < 0? -X[i]: X[i])) < ans)
				ans = x;
}

void write()
{
	freopen("wanted.out", "w", stdout);

	printf("%d\n", ans);
}

int main()
{
	read();

	solve();

	write();

	return 0;
}