版权声明:转载请注明出处链接 https://blog.csdn.net/qq_43408238/article/details/89504823
明天就是运动会啦,平白多了两天的假期,真好,可以放松一下,当然,题目也是不能放下的,正好也可以补补以前的坑。
搜索专题也快结束了,我现在对BFS状态的压缩还是有些迷。第一次接触觉得很神奇,靠一个整型就可以枚举二三十种状态,这也改变了我对位运算的看法,位运算真的叼。
老师又开了二分专题,由二分查找引入二分思想,可以解决很多实际问题。
一个问题让你求某种最优(最大、最小),如果你发现这个问题的函数模型具有某种单调相关性的话,可以尝试一下二分思想。
解题步骤:
1.确定答案的最大值和最小值
2.判断二分所得值是否满足条件
3.可行解必须具有单调性(当k可行时,k+1可行或者k-1可行)
注意事项:
每次都要确保right和left有一个被改变。
模板:
//可行解最大值问题
int l=minn,r=maxn;
int ans=-1;
while(l<=r)
{
int mid=(l+r)>>1;
if(judge(mid))
{
ans=mid;
l=mid+1;
}
else
r=mid-1;
}
二分查找模板:
查找离散的数
//x:待查找的元素,n:数组集合大小,num:数组单调递增
int low=0,high=n,mid,res=-1;//low:集合下界 high:集合上界
while(low<=high)
{
mid=low+(high-low)/2;//防止low+high过大溢出,mid将集合分割为两部分
if(num[mid]==x) //查找到符合元素x
{
res=mid;
break;
}
else if(num[mid]<x) low=mid+1;//x在右边部分,调整集合下界
else high=mid-1;//x在左边部分,调整集合上界
}//未找到x,则res=-1;
查找连续函数的写法
//x:待查找的值,Caculate():所要查找的函数,在这里单调递增
//需要保证查找的值在区间范围内
double low=“区间下界”,high=“区间上界”,mid;
while(high-low>1.0e-6)
{
mid=low+(high-low)/2;
if(Caculate(mid)<x) low=mid;
else high=mid;
}
常见扩展
——对于某些问题,如果答案具有特定的范围,并且验证答案是否成立的函数具有单调性。则可以在范围内对答案进行二分验证,从而快速确定答案。