放牧代码和思想
专注自然语言处理、机器学习算法
    愛しさ 優しさ すべて投げ出してもいい

POJ 3258 River Hopscotch 题解 《挑战程序设计竞赛》

POJ 3258 River Hopscotch

奶牛跳房子:从N块石头中移除M块,使得间距最小值最大。

3.1不光是查找值!“二分搜索”

最大化最小值

再听会儿金融课我就要变蠢了

终于刷到中级篇了,这题是POJ2456的变形,可以想象成从N块石头里挑出N-M块,使得最小间距最大。在实现上,需要贪心地选取比间距d稍微大那么一点(尽量小)的作为编号小的石头,所以需要排个序再去搜索。

举个例子:

0 2 11 14 17 21 25 
5
---------13
3
7
不满足
---------6
2
4
6
7
不满足
---------3
2
3
4
5
满足
---------4
2
4
5
6
满足
---------5
2
4
6
7
不满足
所以答案是4
#ifndef ONLINE_JUDGE
#pragma warning(disable : 4996)
#endif
#include <iostream>
#include <algorithm>
using namespace std;
#define MAX_N 50000 + 16
int L, N, M;
int D[MAX_N];


//************************************
// Method:    C
// FullName:  C
// Access:    public 
// Returns:   bool
// Qualifier: 是否可能使得所有石头之间的距离不小于d
// Parameter: int d
//************************************
bool C(int d)
{
	int last = 0;
	for (int i = 1; i < N - M; ++i)
	{
		int current = last + 1;
		while (current < N && D[current] - D[last] < d)	// 搜寻满足条件的最小位置
		{
			++current;
		}
		if (current == N)	// 都不满足条件
		{
			return false;
		}
		last = current;		// 继续搜寻下一个满足条件的最小位置,放置下一个空位
	}
	return true;
}

///////////////////////////SubMain//////////////////////////////////
int main(int argc, char *argv[])
{
#ifndef ONLINE_JUDGE
	freopen("in.txt", "r", stdin);
	freopen("out.txt", "w", stdout);
#endif
	cin >> L >> N >> M;
	for (int i = 1; i <= N; ++i)
	{
		cin >> D[i];
	}
	++N;	// 0号是起始点,所以加一
	D[N] = L;
	++N;	// N号是结束点,还要加一
	sort(D, D + N);
	int lb = 0, ub = L + 1;
	while (ub - lb > 1)
	{
		int mid = (lb + ub) / 2;
		if (C(mid))
		{
			lb = mid;
		}
		else
		{
			ub = mid;
		}
	}
	cout << lb << endl;

#ifndef ONLINE_JUDGE
	fclose(stdin);
	fclose(stdout);
	system("out.txt");
#endif
	return 0;
}
///////////////////////////End Sub//////////////////////////////////

知识共享许可协议 知识共享署名-非商业性使用-相同方式共享码农场 » POJ 3258 River Hopscotch 题解 《挑战程序设计竞赛》

评论 欢迎留言

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

我的作品

HanLP自然语言处理包《自然语言处理入门》