poj--2456

题意:有N间牛舍,有M头牛,要合理的安排一个最大距离,使得这些牛不能够相互攻击到。

思路:

  这题也是设计到了最大化问题,即奶牛之间两两距离最大,可以考虑二分查找的思路

  同样的这题也要考虑一下贪心策略,要把奶牛先安置在比较靠前的牛舍中

  首先第0个宿舍肯定要入住奶牛的,所以就要考虑从1到M-1个奶牛的宿舍问题了

  这题的判断是否成立的条件也是关键

  

bool is_ok(int x)
{
    int cur;
    int last=0;
    for(int i=1;i<M;i++)//这儿有个小问题就是为什么不是从0开始 
     //因为第0个房子一定要装一头奶牛的,所以要从第二头奶牛开始考虑 
    {
        cur=last+1;
        while(cur<N && (dom[cur]-dom[last])<x)//当前的宿舍要小于N,并且这个宿舍之间的距离还要小于x 
        {
            cur++;
        }
        if(cur==N)    return false;//到达了最后一个宿舍说明没有成立的就返回FALSE 
        last=cur;//要是不是那么就要把last这个中间变量重新赋值 
    }
    return true;
}

然后二分查找可以设置一个精度值,因为都是int类型的变量,完全可以用1来作为精度

二分查找很好实现所以下面直接贴出完整的代码吧

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int N,M;
int dom[100002];
const int INF=1e9;
bool is_ok(int x)
{
    int cur;
    int last=0;
    for(int i=1;i<M;i++)//这儿有个小问题就是为什么不是从0开始 
     //因为第0个房子一定要装一头奶牛的,所以要从第二头奶牛开始考虑 
    {
        cur=last+1;
        while(cur<N && (dom[cur]-dom[last])<x)//当前的宿舍要小于N,并且这个宿舍之间的距离还要小于x 
        {
            cur++;
        }
        if(cur==N)    return false;//到达了最后一个宿舍说明没有成立的就返回FALSE 
        last=cur;//要是不是那么就要把last这个中间变量重新赋值 
    }
    return true;
}
void solve()
{
    sort(dom,dom+N);//本题要用到贪心算法,要对宿舍先进行排序 
    int low=0;
    int high=INF;
    while(high-low>1)//这儿是利用精确度只要大于1 就可以满足了精确度 
    {
        int mid=(low+high)/2;
        if(is_ok(mid))    low=mid;
        else high=mid;
    }
    printf("%d
",low);
}
int main()
{
    while(cin>>N>>M)
    {
        for(int i=0;i<N;i++)
            cin>>dom[i];
        solve();
    }
    return 0;
}

 

原文地址:https://www.cnblogs.com/acmblog/p/9594057.html