
奶牛跳房子:从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 题解 《挑战程序设计竞赛》
码农场