二分法小结

文章来源:http://www.cnblogs.com/hyl2000/p/5734908.html

NOIP中二分应该是很简单的算法了,去年noip的day2-t1就是裸的二分,这里有两个例题

  1、poj2456: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?(大意就是说有一些牛和牛舍,我们要尽量使最近的两头牛之间的距离最大)

  2、跳石头(noip2015-day2-t1):每年奶牛们都要举办各种特殊版本的跳房子比赛,包括在河里从一个岩石跳到另一个岩石。这项激动人心的活动在一条长长的笔直河道中进行,在起点和离起点L远 (1 ≤ L≤ 1,000,000,000) 的终点处均有一个岩石。在起点和终点之间,有N (0 ≤ N ≤ 50,000) 个岩石,每个岩石与起点的距离分别为Di (0 < Di < L)。在比赛过程中,奶牛轮流从起点出发,尝试到达终点,每一步只能从一个岩石跳到另一个岩石。当然,实力不济的奶牛是没有办法完成目标的。农夫约翰为他的奶牛们感到自豪并且年年都观看了这项比赛。但随着时间的推移,看着其他农夫的胆小奶牛们在相距很近的岩石之间缓慢前行,他感到非常厌烦。他计划移走一些岩石,使得从起点到终点的过程中,最短的跳跃距离最长。他可以移走除起点和终点外的至多(0 ≤ M ≤ N) 个岩石。请帮助约翰确定移走这些岩石后,最长可能的最短跳跃距离是多少?(简单来说就是使最小值最大)

  这类问题有个明显的特征:使最小值最大或者使最大值最小。这个时候大概步骤就是先对读进来的数据进行排序(因为二分查找是在有序的数据上进行的)然后执行二分。其中二分里的check函数是最关键的部分,例如第一题中我们就是二分答案,然后在check中贪心的来安排牛的位置,看是否能够满足答案。而第二题也是二分答案,check中按我们求出的答案把不满足答案的石头撤掉,看是否能够满足答案。这就是check的大概思路:即检查是否能够满足答案。

  二分中还有一个重要的细节:求最大值的最小值时mid=(l+r)/2,l=mid+1,r=mid;而查找最小值的最大值时mid=(l+r+1)/2,l=mid,r=mid-1。不然程序会陷入死循环,或者得不到正确答案。

  最后一点就是实数二分的时候因为精度需要常常我们会让程序一直进行计算,然而由于计算时的精度误差,常常也会使程序效率低下或者死循环。一般来讲我们这时可以限制二分次数,一般60-70次即可满足精度需要,这样可以提高程序效率,避免TLE的情况出现。

  最最后一点,这类问题数据量一般都非常大,记得用scanf读入,第一题我就因为用cin而TLE了,改成scanf之后马上就过了。。。。。

原文地址:https://www.cnblogs.com/huashanqingzhu/p/7617611.html