Hdu 1025 Constructing Roads In JGShining's Kingdom

大意不再赘述。

思路:这一题与POJ 1631 Bridging signals 非常相似,但这一题的隐藏条件需要细心地思考才会得出结果,而且输出时有1个Trap,road和roads,另外由于数据量巨大,所以单纯的DP是过不了的,需要利用二分的方法确定d[i]的值。

#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
using namespace std;

const int MAXN = 500010;
const int INF = 0x3f3f3f3f;

int n;
int times;
int A[MAXN];
int d[MAXN];
int S[MAXN];

void read_case()
{
	for(int i = 1; i <= n; i++)
	{
		int x, y;
		scanf("%d%d", &x, &y);
		A[x] = y;
	}
}

void init()
{
	for(int i = 1; i <= n; i++) S[i] = INF;
	d[0] = 0;
}

int BSearch(int x, int y, int v)
{
	while(x <= y)
	{
		int mid = x+(y-x)/2;
		if(S[mid] <= v) x = mid+1;
		else y = mid-1;
	}
	return x;
}

void dp()
{
	init();
	int ans = 0;
	for(int i = 1; i <= n; i++)
	{
		int x = 0, y = i;
		int pos = BSearch(x, y, A[i]);
		d[i] = pos;
		S[d[i]] = min(S[d[i]], A[i]);
		ans = max(ans, d[i]);
	}
	if(ans == 1) printf("My king, at most 1 road can be built.\n\n");
	else printf("My king, at most %d roads can be built.\n\n", ans);
}

void solve()
{
	read_case();
	printf("Case %d:\n", ++times);
	dp();
}

int main()
{
	times = 0;
	while(~scanf("%d", &n))
	{
		solve();
	}
	return 0;
}


你可能感兴趣的:(Hdu 1025 Constructing Roads In JGShining's Kingdom)