【二分答案】附通用模板

一、什么是二分答案

二分答案 是一种逆向二分思想:不去直接求题目要求的解,而是猜测一个答案 ,再用 check() 函数验证这个答案是否合法/可行。

适用前提(缺一不可)

  1. 答案有确定范围(有最小值、最大值)
  2. 答案具有单调性
    • mid 可行,则比 mid 更大/更小的解也一定可行
    • mid 不可行,则相反方向的解也一定不可行

常见题型

  • 最大值最小化(最小化最大值)
  • 最小值最大化(最大化最小值)
  • 满足条件的第 k 大/小值
  • 最值类判定问题

二、核心逻辑总流程

  1. 确定答案范围 :左边界 l、右边界 r
  2. 二分缩区间 :不断取中间值 mid
  3. 校验函数 check(mid) :判断 mid 这个答案是否满足题意
  4. 根据 check 结果移动边界,缩小区间
  5. 区间收敛后,得到最终最优解

三、两大经典模板(竞赛/刷题通用)

二分答案分两类高频场景:

  • 场景 1 :求「满足条件的最小值」(越小越严格)
  • 场景 2 :求「满足条件的最大值」(越大越严格)

模板 1:求「满足条件的最小答案」

题意 :找到最小的 ans,使得 check(ans) = true

单调性

  • mid 可行 → 尝试找更小的解:r = mid
  • mid 不可行 → 必须增大:l = mid + 1
cpp 复制代码
// 二分答案:求最小可行解
int l = 下界, r = 上界;
while (l < r) {
    int mid = l + (r - l) / 2;  // 防溢出,等价 (l+r)/2
    if (check(mid)) {
        r = mid;   // mid 可行,往左找更小解
    } else {
        l = mid + 1; // mid 不行,右移
    }
}
// 最终 l == r,即为最小答案
cout << l;

执行过程演示(举例)

假设范围 l=1, r=10,要找最小可行值,规则:≥6 都可行

复制代码
l=1, r=10 → mid=5,check(5)=false → l=6
l=6, r=10 → mid=8,check(8)=true → r=8
l=6, r=8 → mid=7,check(7)=true → r=7
l=6, r=7 → mid=6,check(6)=true → r=6
l == r = 6,循环结束,答案为 6

模板 2:求「满足条件的最大答案」

题意 :找到最大的 ans,使得 check(ans) = true

单调性

  • mid 可行 → 尝试找更大的解:l = mid
  • mid 不可行 → 必须减小:r = mid - 1

⚠️ 此处 mid 必须写成 mid = l + (r - l + 1) / 2,防止死循环

cpp 复制代码
// 二分答案:求最大可行解
int l = 下界, r = 上界;
while (l < r) {
    int mid = l + (r - l + 1) / 2; // 向上取整,避免死循环
    if (check(mid)) {
        l = mid;   // mid 可行,往右找更大解
    } else {
        r = mid - 1; // mid 不行,左移
    }
}
// 最终 l == r,即为最大答案
cout << l;

执行过程演示(举例)

范围 l=1, r=10,规则:≤7 都可行,求最大可行值

复制代码
l=1,r=10 → mid=6,check(6)=true → l=6
l=6,r=10 → mid=8,check(8)=false → r=7
l=6,r=7 → mid=7,check(7)=true → l=7
l==r=7,结束,答案为 7

四、关键组件:check 校验函数

check(x) 是二分答案的灵魂

作用 :给定一个假设答案 x,判断题目规则是否能被满足

格式统一思路

cpp 复制代码
// 参数 x:当前猜测的答案
bool check(int x) {
    // 模拟题目规则、统计、判断是否合法
    // 合法 return true,不合法 return false
}

不同题型 check 写法不同,但逻辑固定:模拟题意验证

五、完整通用解题四步(做题直接套用)

步骤 1:分析题意,判断能否用二分答案解

  • 有明确上下界
  • 解具备单调性

步骤 2:确定二分边界 l、r

  • l:理论最小值(常取 0 / 题目最小限制)
  • r:理论最大值(常取 数据上限 / 题目最大限制)

步骤 3:选择对应模板

  • 最小可行解 → 模板 1
  • 最大可行解 → 模板 2

步骤 4:编写 check 函数(模拟题意校验)

六、实战示例(带你完整走一遍)

例题场景 :把 n 个物品分成 m 组,每组和不超过 x,求每组和的最小最大值(经典二分答案题)

数组:[4,2,5,1,3],分成 3 组

1. 确定边界

  • 最小可能:数组最大值 5
  • 最大可能:数组总和 15
  • l=5, r=15

2. 目标:求最小的最大和 → 使用 模板 1(最小可行解)

3. 写 check(x):判断能否分成 ≤3 组,每组和 ≤x

cpp 复制代码
// 校验:能否分成不超过 m 组,每组和不超过 x
bool check(int x, vector<int>& a, int m) {
    int cnt = 1;    // 初始1组
    int sum = 0;
    for (int num : a) {
        if (sum + num > x) {
            cnt++;
            sum = num;
            if (cnt > m) return false;
        } else {
            sum += num;
        }
    }
    return true;
}

4. 套模板运行

cpp 复制代码
int main() {
    vector<int> a = {4,2,5,1,3};
    int m = 3;
    int l = 5, r = 15;
    
    while (l < r) {
        int mid = l + (r - l) / 2;
        if (check(mid, a, m))
            r = mid;
        else
            l = mid + 1;
    }
    cout << l; // 输出答案
    return 0;
}

整段流程:猜值 → 校验 → 缩区间 → 得到最优解。

七、常见易错点总结

  1. mid 写法

    • 求最小解:mid = l + (r-l)/2(向下取整)
    • 求最大解:mid = l + (r-l+1)/2(向上取整)
    • 禁止直接 (l+r)/2,大数据会溢出
  2. 死循环问题

    • 最大解模板必须向上取整 mid,否则 l=r-1 时卡死
  3. 边界 l、r 取值

    • 边界一定要覆盖所有可能答案,偏小/偏大都会 WA
  4. check 函数逻辑

    • 必须严格模拟题目规则,是二分答案最容易出错的地方

八、一句话记忆口诀

答案有界又单调,二分答案就能搞;

猜个 mid 先校验,可行不可行分两道;

求最小就往左缩,求最大就往右靠;

mid 取整看模板,区间收敛出答案。

九、二分答案 vs 二分查找

特性 二分答案 二分查找
目标 求满足条件的最优解(最大/最小值) 有序数组 中查找特定值
输入 通常是一个问题描述约束条件 一个有序数组 和一个目标值
单调性来源 问题的解空间具有单调性 数组本身有序
check函数 核心,模拟题目规则验证假设答案 简单比较 arr[mid]target
应用场景 最优化问题(最大值最小化等) 查找问题(找元素、找边界)
时间复杂度 O(log(范围) × check复杂度) O(log n)

简单理解

  • 二分查找 :在有序数据 中找已知存在的某个值
  • 二分答案 :在可能解的范围 中找满足条件的最优值

举例说明

  • 二分查找:在 [1,3,5,7,9] 中找数字 5
  • 二分答案:求把数组分成3组时,每组和的最小最大值

二分答案是二分思想的高级应用 ,将最优化问题 转化为判定问题(通过check函数),再用二分快速找到最优解。

相关推荐
Shadow(⊙o⊙)2 小时前
C++进阶知识3.0
linux·服务器·开发语言·c++
春栀怡铃声2 小时前
【C++修仙录03】进阶篇:继承
c++
三行数学2 小时前
数学周刊第23期(2026年06月08日-06月14日)南师数科院万仁辉副教授成果登顶国际数学四大顶刊之一<数学年刊>
算法·数学周刊
.千余2 小时前
【C++】C++ map 与 multimap 完全指南:键值对容器详解
开发语言·c++·笔记·学习·其他
Frank学习路上2 小时前
【C++】面试:内存管理
c++·面试
牢姐与蒯2 小时前
c++数据结构之c++11(三)
开发语言·c++
阿文的代码库2 小时前
算法专题:独特的电子邮件地址
linux·运维·算法
老饼讲解-BP神经网络2 小时前
BP神经网络用什么训练算法(traingd、traingdm、trainlm)
人工智能·神经网络·算法
Irissgwe2 小时前
数据结构-二叉树
数据结构·c++·二叉树·c·