对于二分我们最初的了解,就是在一个一次函数中,对于要求的点,(x,y)已知y,对于包含x值的区间二分,根据函数值与y比较,逐步靠近要求的点,直到最终求出要求的点。
在程序执行时,二分的时间复杂度为logn,可以极大的减少查找的时间。
二分的应用
严格来讲答案具有单调性的问题都可以用二分来解决,对于答案类似于一个一次函数,通过不断判断答案是否满足缩小区间。
1:求最大值中的最小值:
对所给区间进行二分,判断时,认为,时最大值中找最小的答案,所以这个答案如果比这个最小的答案要大,那么他也是可以成立的,它就可能是我们想要求得值,因此,在这给它做一个记录,ans=mid;这个答案最终的判断标准是很重要的。
例题:
将一个n个数组成的数列分成m段要求每段和的最大值最小:
将数组最小值跟最大值作为二分的左右值,贪心判断二分答案是否正确。
贪心过程大致为,对于可能存在的答案mid,将原数组相加,求得的值如果大于mid,cnt++,最后得到的cnt如果小于m,就说明我们取得这个最大值,大了(根据我们上面的分析,虽然它太大了,但它作为最大值而言是合乎提议的,因此,要使ans=mid),不是我们想要的最小值,那么我们就将它变小,并且使ans=mid。
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
using namespace std;
int n,m,a[100005];
int solve(int x)
{
int sum=0,cnt=0;
for(int i=0;i<n;i++)
{
if(sum+a[i]<=x)
sum+=a[i];
else
sum=a[i],cnt++;
}
if(cnt>=m)
return 1;
else
return 0;
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
int r=0,l=0,ans;
for(int i=0;i&l