zoukankan      html  css  js  c++  java
  • 二分

    定义:二分的基础用法是在单调序列或者单调函数中进行查找。
    根据复杂度理论,我们可以通过将求解改为判定的方法,优化算法。这是一种非常基础,又比较容易写错的算法。本文将阐述一种常见的二分方法。

    整数集合上的二分

    保证最终答案处于闭区间 $ [l,r] $ 以内,循环以 $ l == r $ 结束,每次二分的中间值会归属于左半段或者右半段。

    应用
    单调递增序列求 $ x $ 或 $ x $ 的后继:

    	while (l < r) {
    		mid = (l + r) / 2;
    		if (a[mid] >= x) r = mid;
    		else l = mid + 1;
    	}
    

    单调递增序列求 $ x $ 或 $ x $ 的前驱:

    	while (l < r) {
    		mid = (l + r + 1) / 2;
    		if (a[mid] <= x) l = mid;
    		else r = mid - 1;
    	}
    

    注意:可行解一定要在选取的区间之内,一定不能造成没有缩小可行区域的情况

    如上面两种代码所示,这种闭区间的二分有两种形式

    1. 缩小范围时,$ r = mid $, (l = mid + 1),取中间值时,(mid = (l + r) / 2)
    2. 缩小范围时,$ l = mid $, (r = mid - 1),取中间值时,(mid = (l + r + 1) / 2)

    思考一下,如果第二种情况仍然使用 (mid = (l + r) / 2), 如果 (r - l == 1) 那么 (mid) 的值就会和 (l) 一样,会造成没有缩小可行区域的情况,进入死循环
    仔细分析这两种 (mid) 的取值,我们还发现:(mid = (l + r) / 2) 不会取到 (r) 这个值,(mid = (l + r + 1) / 2) 不会取到 (l) 这个值。我们可以利用这一性质来处理无解的情况,即:把最初的二分区间 ([1,n]) 变成 ([0,n]) 或者 ([1, n+1]),如果最终结果在这两个不存在的值上,那就是没有答案。
    因此,使用配套(mid) 取法时必须的。

    至此,整数域的二分已经讲完,采用" (l = mid + 1, r = mid - 1) " 或 “ (l = mid, r = mid) "的代码形势也很常见,但是在这里不做过多的阐述

    实数域上的二分

    实数域上的二分比较简单,设置精度,然后直接二分就可以。

    while (l + eps < r) {
        double mid = (l + r) / 2;
        if (calc(mid)) r = mid; else l = mid;
    }
    
  • 相关阅读:
    jsp mysql 实现客户端简单分页查询
    jsp mysql 实现客户端简单数据的修改和删除
    jsp 简单把数据库数据,展示在网页
    XML当做数据库,完成增删查
    xml的增删查 dom的增改查 复杂注释
    修改目录下所有文件时间
    打开调试模式
    强化学习笔记4:无模型预测 model-free prediction
    强化学习笔记6:值函数估计Value function Approximation
    Declarative Pipeline语法介绍
  • 原文地址:https://www.cnblogs.com/Alessandro/p/9709649.html
Copyright © 2011-2022 走看看