Cod sursa(job #900104)

Utilizator alex_unixPetenchea Alexandru alex_unix Data 28 februarie 2013 17:41:00
Problema Secv Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.95 kb

#include <cstdio>
#include <algorithm>
#include <vector>

const int MAX_SIZE(5001);
const int MAX_VALUE(1 << 30);

int n, m, optimal(1 << 30);
int v [MAX_SIZE];
int a [MAX_SIZE];

std::vector <int> hash [MAX_SIZE];
int dp [MAX_SIZE];

inline void read (void)
{
	std::freopen("secv.in","r",stdin);
	std::scanf("%d",&n);
	for (int i(1) ; i <= n ; ++i)
	{
		std::scanf("%d",&v[i]);
		a[i] = v[i];
	}
	std::fclose(stdin);
}

inline void print (void)
{
	std::freopen("secv.out","w",stdout);
	std::printf("%d\n",optimal);
	std::fclose(stdout);
}

inline int search (int left, int right, int x)
{
	int middle((left + right) >> 1);
	while (left < right)
	{
		if (a[middle] < x)
			left = middle + 1;
		else
			right = middle;
		middle = (left + right) >> 1;
	}
	return middle;
}

inline void normalize (void)
{
	std::sort(a + 1,a + n + 1);
	int i, j;
	for (i = 1, j = 1 ; i <= n ; ++i)
		if (a[i] != a[i - 1] || i == 1)
		{
			a[j] = a[i];
			++j;
		}
	m = j - 1;
	for (i = 1 ; i <= n ; ++i)
	{
		v[i] = search(1,m,v[i]);
		hash[v[i]].push_back(i);
	}
}

inline void dynamic (void)
{
	int i, j, end, left, right, middle;
	for (j = 0, end = hash[m].size() ; j < end ; ++j)
		dp[hash[m][j]] = 1;
	for (i = m - 1 ; i ; --i)
		for (j = 0, end = hash[i].size() ; j < end ; ++j)
		{
			left = 0;
			right = hash[i + 1].size() - 1;
			middle = (left + right) >> 1;
			while (left < right)
			{
				if (hash[i + 1][middle] < hash[i][j])
					left = middle + 1;
				else
					right = middle;
				middle = (left + right) >> 1;
			}
			if (dp[hash[i + 1][middle]] == MAX_VALUE)
				dp[hash[i][j]] = MAX_VALUE;
			else if (hash[i + 1][middle] > hash[i][j])
				dp[hash[i][j]] = dp[hash[i + 1][middle]] + hash[i + 1][middle] - hash[i][j];
			else
				dp[hash[i][j]] = MAX_VALUE;
		}
	for (i = 0, end = hash[1].size() ; i < end ; ++i)
		if (dp[hash[1][i]] < optimal)
			optimal = dp[hash[1][i]];
	if (optimal == MAX_VALUE)
		optimal = -1;
}

int main (void)
{
	read();
	normalize();
	dynamic();
	print();
	return 0;
}