Cod sursa(job #1457823)

Utilizator tamionvTamio Vesa Nakajima tamionv Data 4 iulie 2015 15:42:45
Problema Wanted Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.34 kb
#include <fstream>
#include <iostream>
#include <vector>
#include <utility>
#include <limits>
#include <algorithm>
using namespace std;

constexpr unsigned int inf = numeric_limits<decltype(inf)>::max();

int dist(const int a, const int b){
	return (a < b) ? (b-a) : (a-b); }

int dist(const pair<int, int> a, const pair<int, int> b){
	return dist(a.first, b.first) + a.second + b.second; }

template <typename T>
class triang_mat{
	vector<vector<T> > buf;
public:
	triang_mat(const int sz, const T t){
		buf.resize(sz);
		for(int i = 0; i < sz; ++i){
			buf[i].resize(sz-i, t); } }
	T& la(const int a, const int b){
		return buf[a][b-a]; } };

int main(){
	ifstream f("wanted.in");
	ofstream g("wanted.out");
	int n;
	f >> n;
	vector<pair<int, int> > v(n);
	for(auto& x : v){
		f >> x.first >> x.second; }
	sort(begin(v), end(v), [](const pair<int, int> a, const pair<int, int> b){
		return a.first < b.first; });
	triang_mat<vector<unsigned int> > d(v.size(), vector<unsigned int>(v.size(), 0));
	for(int nod = 0; nod < v.size(); ++nod){
		for(int de_la = 0; de_la < v.size(); ++de_la){
			if(nod == de_la){
				d.la(nod, nod)[de_la] = 0; }
			else{
				d.la(nod, nod)[de_la] = dist(v[nod], v[de_la]); } } }
	
	for(int delta = 2; delta <= v.size(); ++delta){
		for(int st = 0, fin = st+delta-1; fin < v.size(); ++st, ++fin){
			d.la(st, fin)[st] = d.la(st+1, fin)[st];
			d.la(st, fin)[fin] = d.la(st, fin-1)[fin];
	
			for(int de_la = st+1; de_la < fin; ++de_la){
				d.la(st, fin)[de_la] = max(
					d.la(st, de_la-1)[de_la],
					d.la(de_la+1, fin)[de_la]); }

			pair<int, int> left_point(v[st].first, 0),
				right_point(v[fin].first, 0);
			unsigned int left_point_best = inf,
				right_point_best = inf;

			for(int dest = st; dest <= fin; ++dest){
				left_point_best = min(left_point_best,
					(dist(left_point, v[dest]) +
					d.la(st, fin)[dest]));
				right_point_best = min(right_point_best,
					(dist(right_point, v[dest]) +
					d.la(st, fin)[dest])); }

			for(int de_la = 0; de_la < st; ++de_la){
				d.la(st, fin)[de_la] = dist(v[de_la], left_point)
					+ left_point_best; }
			for(int de_la = fin+1; de_la < v.size(); ++de_la){
				d.la(st, fin)[de_la] = dist(v[de_la], right_point)
					+ right_point_best; } } }
	unsigned int rez = inf;
	for(int i = 0; i < v.size(); ++i){
		rez = min(rez, d.la(0, v.size()-1)[i] + dist(make_pair(0, 0), v[i])); }
	g << rez;
	return 0; }