开学第九周.One(二分及其思想)

版权声明:转载请注明出处链接 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;
}

常见扩展

——对于某些问题,如果答案具有特定的范围,并且验证答案是否成立的函数具有单调性。则可以在范围内对答案进行二分验证,从而快速确定答案。

猜你喜欢

转载自blog.csdn.net/qq_43408238/article/details/89504823
今日推荐