Cod sursa(job #137520)

Utilizator ProstuStefan-Alexandru Filip Prostu Data 17 februarie 2008 12:32:54
Problema Stalpi Scor 0
Compilator cpp Status done
Runda preONI 2008, Runda 4, Clasele 11-12 Marime 1.37 kb
#include <cstdio>
#include <algorithm>

using namespace std;

const int NMAX = 1 << 17;
const int INF = 0x3f3f3f3f;

int N;
int X[NMAX], C[NMAX], S[NMAX], D[NMAX];
int V[NMAX], CX[NMAX], Q[NMAX], poz[NMAX];
int DP[NMAX];

struct comp {
	bool operator()(const int &a, const int &b) const {
		return X[a] + S[b] < X[b] + S[a];
	}
};

void read(void) {
	FILE *fin = fopen("stalpi.in", "rt");
	int i;

	fscanf(fin, " %d", &N);

	for (i = 1; i <= N; ++i) {
		fscanf(fin, " %d %d %d %d", X + i, C + i, S + i, D + i);
		V[i] = i; CX[i] = X[i];
	}

	fclose(fin);
}

void dinamica(void) {
	int i, u, v, cs, cd, beg, end;

	CX[0] = X[0] = -INF; S[0] = INF;
	sort(V, V + N + 1, comp());
	sort(CX, CX + N + 1);
	memset(DP, 0x3f, sizeof(DP));
	DP[0] = 0;

	beg = 0; end = -1;
	for (i = 1; i <= N; ++i) {
		u = V[i];
		cs = upper_bound(CX, CX+N+1, X[u]-S[u]) - CX - 1;
		cd = upper_bound(CX, CX+N+1, X[u]+D[u]) - CX - 1;
		
		v = DP[cs];
		if (beg <= end && v > Q[beg]) v = Q[beg];

		DP[cd] = min(DP[cd], v + C[u]);
//		printf("%d %d %d %d %d\n", i, u, cs, cd, v);

		while (beg <= end && poz[beg] <= i) ++beg;
		while (beg <= end && Q[end] > DP[cd]) --end;
		++end; Q[end] = DP[cd]; poz[end] = cd;

		DP[i] = min(DP[i], Q[beg]);
	}
}

void write(void) {
	FILE *fout = fopen("stalpi.out", "wt");

	fprintf(fout, "%d\n", DP[N]);

	fclose(fout);
}

int main(void) {

	read();

	dinamica();

	write();

	return 0;
}