疯牛

另外一个贪心算法的例子,题目是这样的

疯牛

时间限制: 1000 ms  |  内存限制: 65535 KB
难度: 4
描述
农夫 John 建造了一座很长的畜栏,它包括N (2 <= N <= 100,000)个隔间,这些小隔间依次编号为x1,...,xN (0 <= xi <= 1,000,000,000).
但是,John的C (2 <= C <= N)头牛们并不喜欢这种布局,而且几头牛放在一个隔间里,他们就要发生争斗。为了不让牛互相伤害。John决定自己给牛分配隔间,使任意两头牛之间的最小距离尽可能的大,那么,这个最大的最小距离是什么呢?
输入

下面是我查了网上的文章后自己总结的解题思路:

  1. 先把所有的隔间位置按从小到大排序,于是有1  2  4  8  9,于是题目转化成在1~9之间找到一个数,使它与1和9的距离的最小值最大,也就是越靠近中间越符合要求
  2. 运用二分枚举法找出这个距离的最小值。最小值有好几个,有1 ( 1 ->2->x,  x->8->9)  2 ( 2 ->4->8, 2->4->9 ) 3 (1->4->8, 1->4->9)
  3. 但还要找到最小值里的最大值,于是要用到贪心算法找到最大值。

二分枚举的框架是这样的

while(low<high)
{
int mid = (low+high)/2;
if(<)low = mid+1;    // mid取的太小了
else high = mid;
}

下面是这题的代码。

以6 3 +  1  2  4  8  9这组输入 来解释下面的代码

首先把题目转换成在一条距离为8的线段内找到一K(K=1)个点,使得这个点到另外几个点的最短距离最大

  1.               用二分枚举法,初始状态 low=0,high=8, mid=4
  2.               调用check()函数,目的是遍历所有的数据,找到至少C(C=3)个点使得这几个点的距离至少为mid(mid=4)
  3.              显然找不到这样一个点,使它到1和9的距离都>=4. 说明mid选大了,于是high-1,使mid变小点;
  4.              同理,如果找到了至少C个点,那说明mid选小了,于是low+1,使mid变大点;

      

#include"iostream"
#include "stdlib.h"
#include "stdio.h"
#include "algorithm"
using namespace std;


int N,C;  //N 表示隔间的数目,C 表示牛的数目

bool check(int *(&a),int mid)
{
  int temp=a[0];
  int cow=1; // 表示符合要求的牛的数目
  for(int i=1;i<N;i++)
  {
    if(a[i]-temp>=mid)  //每找到一个符合要求的牛
      {
        cow++;
        temp=a[i];
      }
    if(cow>=C)
    return true;
  }
  return false;
}

int binary_enum(int *(&a))
{
   int low = 0;
   int high=a[N-1]-a[0];
   int mid;
   while(low<=high)
   {
     mid=(low+high)/2;
     if(check(a,mid)) low=mid+1;
     else high=mid-1;
     
   }
   return low-1;
} 
int main()
{
  while(EOF!=scanf("%d%d",&N,&C))
  {
    int *a=new int[N];
    int i;
    for(i=0;i<N;i++)
       cin>>a[i];
    sort(a,a+N);
    cout<<binary_enum(a)<<endl;
    delete a;
  }

return 0;
}



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值