1. 程式人生 > >POJ 2456 Aggressive cows (貪心 + 二分)

POJ 2456 Aggressive cows (貪心 + 二分)

Aggressive cows
Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 9797 Accepted: 4865

Description

Farmer John has built a new long barn, with N (2 <= N <= 100,000) stalls. The stalls are located along a straight line at positions x1,...,xN (0 <= xi <= 1,000,000,000). 

His C (2 <= C <= N) cows don't like this barn layout and become aggressive towards each other once put into a stall. To prevent the cows from hurting each other, FJ want to assign the cows to the stalls, such that the minimum distance between any two of them is as large as possible. What is the largest minimum distance?

Input

* Line 1: Two space-separated integers: N and C 

* Lines 2..N+1: Line i+1 contains an integer stall location, xi

Output

* Line 1: One integer: the largest minimum distance

Sample Input

5 3
1
2
8
4
9

Sample Output

3

Hint

OUTPUT DETAILS: 

FJ can put his 3 cows in the stalls at positions 1, 4 and 8, resulting in a minimum distance of 3. 

Huge input data,scanf is recommended.

最大化最小值

農夫約翰搭了一間有n間牛舍的小屋。牛舍排在一條線上第i號牛舍在xi的位置。但是他的m頭牛對小屋很不滿意,因此經常互相攻擊。約翰為了防止牛之間互相傷害,因此決定把每頭牛都放在離其他牛儘可能遠的牛舍。也就是要最大化最近的兩頭牛之間的距離

分析:

我們定義C(d):=可以安排牛的位置是的最近的兩頭牛的距離不小於d

那麼問題就變成了求滿足C(d)的最大值的d。另外,最近的間距不小於d也可以說成是所有牛的間距都不小於d,因此就有

C(d) = 可以安排牛的位置使得任意的牛的間距都不小於d

這個問題的判斷使用貪心法便可以非常容易的求解。

1.       對牛舍的位置x進行排序

2.       把第一頭牛放入x0的牛舍

3.       如果第i頭牛放入了xj的話,第i+ 1頭牛就要放入滿足xj + d <= xk的最小的xk中

對x的排序只需在最開始時進行一次就可以了,每一次判斷對每頭牛最多進行一次處理,因此複雜度是O(N)。

//最大化最小值
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn = 100000 + 10;
const int INF = 100000000;

int n, m;
int x[maxn];

bool C(int d)
{
    int last = 0;
    for (int i = 1; i < m; i++){
        int crt = last + 1;
        while (crt < n && x[crt] - x[last] < d){
            crt++;
        }
        if  (crt == n)
            return false;
        last = crt;
    }
    return true;
}

void solve()
{
    //從最開始對x陣列排序
    sort(x, x + n);

    //初始化解的存在範圍
    int lb = 0, ub = INF;

    while (ub - lb > 1){
        int mid = (lb + ub) / 2;
        if (C(mid))
            lb = mid;
        else
            ub = mid;
    }
    printf("%d\n", lb);
}

int main()
{
    while (scanf("%d%d", &n, &m) != EOF){
        for (int i = 0; i < n; i++){
            scanf("%d", &x[i]);
        }
        solve();
    }
    return 0;
}