二分答案题解:单调性不成立,就别硬套模板

📅 2026/7/5 1:58:32
二分答案题解:单调性不成立,就别硬套模板
二分答案题解单调性不成立就别硬套模板一、二分答案不是看见最大最小就用二分答案题经常出现在“最小化最大值”“最大化最小值”这类描述里。但不是所有带最大最小的题都能二分。核心条件是判定函数具有单调性。没有单调性模板写得再熟也会错。做题时先问一句如果答案 x 可行那么更大或更小的答案是否必然可行。如果这个关系不能证明就不要急着写二分。算法模板只是表达形式单调性才是正确性的根。二、判定函数决定题目结构flowchart TD A[候选答案 mid] -- B[判定函数 check] B -- C{是否可行} C -- 可行 -- D[收缩一侧] C -- 不可行 -- E[收缩另一侧] D -- F[最终答案] E -- F二分答案通常把优化问题转成判定问题。比如“最小最大载重”可以转成“给定载重 mid能否在指定天数内完成”。判定函数越清楚二分方向越不容易写反。判定函数要尽量 O(n) 或 O(n log n)。如果 check 本身太慢二分外面再套一层整体复杂度可能不可接受。写题解时要同时分析二分次数和每次判定成本。三、边界写法要统一def binary_answer(left, right, check): while left right: mid (left right) // 2 if check(mid): right mid else: left mid 1 return left上面写法适合找最小可行值。前提是 check(x) 为真后所有更大的 x 也为真。如果题目是找最大可行值边界和 mid 取法要调整避免死循环。def max_feasible(left, right, check): while left right: mid (left right 1) // 2 if check(mid): left mid else: right mid - 1 return left两个模板不要混着用。每次写之前先标注我要找最小可行还是最大可行。这个标注能减少一半边界错误。四、证明要写清方向复杂度分析之外题解还要说明为什么二分方向正确。比如当 mid 可行时说明更大载重也可行因此可以尝试更小值。这个证明很短但不能省。还要检查初始边界。left 应该是不可能更小的下界right 应该是一定可行的上界。边界如果不保证答案在区间内后面循环再正确也没用。二分答案还要注意整数溢出。Python 里问题不明显但 Go、Java、C 中(left right) / 2可能溢出。更稳的写法是left (right - left) / 2。题解如果跨语言讲解最好把这个细节写出来。浮点二分则不适合用left right。通常要固定迭代次数或者在区间长度小于误差时停止。浮点题的正确性还要结合误差范围不要把整数二分模板直接搬过去。判定函数也要避免副作用。有些实现为了省事在 check 里修改全局数组或缓存状态下一轮 mid 就会受到污染。check 应该是纯函数或至少可重复调用这样二分过程才稳定。五、总结二分答案题的关键不是模板而是判定函数和单调性证明。先确认可行性方向再选择最小可行或最大可行写法。看见最大最小不要条件反射。能证明单调二分才有资格登场。