POJ3258 River Hopscotch 二分搜索

        題目大意是,河中有排列一些石頭,石頭所在的位置都不同,可以拿去其中的幾塊石頭,但是開始和結束位置的石頭不能去掉,使得這些石頭之間的最小距離最大。

        這題就是最大化最小值,我們可以用二分搜索來解決這個問題。直接套用二分法的模型,定義C(X):=石頭之間的距離都不小於X。然後進行二分搜索滿足條件的最大X值。

確定石頭距離是否能滿足距離不小於X,只要對石頭排序後,依次判斷當前石頭是否和之前的石頭距離小於X如果小於,則去掉當前石頭,這一步的複雜度O(n),總共的複雜度

便是O(nLog(P)),P爲開始位置和結束位置石頭的距離。

#include <stdio.h>
#include <vector>
#include <math.h>
#include <string.h>
#include <string>
#include <iostream>
#include <queue>
#include <list>
#include <algorithm>
#include <stack>
#include <map>

using namespace std;

int StonePos[50003];
int Dis[50003];

bool CC(int x, int N, int M)
{
	int curcount = 0;
	int curLeft = -1;
	for (int i = 0; i < N;i++)
	{
		if (Dis[i] < x)
		{
			if (i == N - 1 && curcount < M)
			{
				if (curLeft >= 0)
				{
					if (Dis[i] + curLeft < x)
					{
						return false;
					}
				}
				else
					return false;
			}
			else if (curcount < M)
			{
				Dis[i + 1] += Dis[i];
				curcount++;
			}
			else
				return false;
		}
		else
		{
			curLeft = i;
		}
	}
	return true;
}

int compp(const void* a1, const void* a2)
{
	return *(int*)a1 - *(int*)a2;
}


int main()
{
#ifdef _DEBUG
	freopen("e:\\in.txt", "r", stdin);
#endif
	int L, N, M;
	scanf("%d %d %d\n", &L, &N, &M);
	StonePos[0] = 0;
	for (int i = 1; i <= N;i++)
	{
		scanf("%d\n", &StonePos[i]);
	}
	StonePos[N + 1] = L;
	qsort(StonePos, N + 2, sizeof(int), compp);
	for (int i = 0; i <= N;i++)
	{
		StonePos[i] = StonePos[i + 1] - StonePos[i];
	}
	int l = 0;
	int r = L * 2;
	while (r - l > 1)
	{
		memcpy(Dis, StonePos, sizeof(Dis));
		int mid = (l + r) / 2;
		if (CC(mid, N + 1, M))
		{
			l = mid;
		}
		else
			r = mid;
	}
	printf("%d\n", l);
	return 0;
}




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章