二分求最值
今日的二分求最值搞得我头有点大,主要题目都是英文的,都没怎么看明白题目(最小值最大&&最大值最小)。
先来一波自己的理解23333:
题目一般要求在一段长度上面取走某个点或者是添加某个点,然后求出剩下的点的最大值的最小情况或最小值的最大情况。要二分得先排个序,在进行二分,第一次对线段的头和尾进行二分,然后逐渐进行二分,每一次二分的时候都要判断二分得到的值是否符合条件,如果符合条件那么就让二分的值更小或更大(具体看题),否则反之。如何判断符合条件呢?就要在外面设置一个函数,设judge(int mid)其中判断的条件要通过题目的条件:
今天安置牛的一题,通过贪心来一个个确定牛的未知是否满足,首先把第一个牛窝放一只牛,每次取牛窝的位置,减去上一个牛窝的位置,如果大于mid的值,那么就可以放一头牛,这样寻找下去,如果最后放下牛的个数多于总共的牛,那么这个mid距离就可以满足,mid就可以更大(让mid更大的步骤就是让下限变为mid上限不变),就是牛之间的距离可以更大;那么如果最后放下的个数少于总共的牛,那么mid就应该小一点来放下更多的牛(同理让上限改为mid-1(减一的目的是防止进入死循环),下限不变),重复上面的步骤,当二分到最接近的值就可以的到答案了。可以看出mid就是最后的答案;
ps:上题是求最小值的最大值改的时候是上限=mid-1;求最小值的最大值时候是将下限=mid+1;
再ps:吐槽一下今天取石子题目里面的坑,头和尾多了两个石头有点搞心态,后来发现了再修改代码,总是漏掉一些地方没改,搞得错了好几次,fxxk!
再上一个别人写的模板2333:
#include<iostream>
using namespace std;
bool judge(int mid)//判断是否符合条件
{
for(循环)
{
求解计数结果num,++num;
}
if(num与题目边界条件)
return true;
else
return false;
}
int main()
{
int l, r, ans = 0;
l = ;//l和r的具体值要看题目是需要枚举的什么
r = ;
while(l <= r)
{
int mid = (l+r)/2;//mid = l + (r-l)/2
if(judge(mid))
{
ans = mid;
l = mid + 1;//也有可能不是1,可能是一个小数,要看具体的间距
}
else
r = mid -1;
}
cout << ans << endl;
return 0;
}