#5413. 二分答案笔记
二分答案笔记
二分答案笔记总结
一、什么是二分答案?
二分答案是一种基于二分查找思想的解题方法,用于求解满足特定条件的最优解(通常是最大值或最小值)。其核心思路是:通过对「可能的答案范围」进行二分,不断缩小范围,最终找到符合条件的最优解。
二分答案的关键前提:问题的解具有单调性。即:
- 若某个值
x满足条件,则所有小于x的值(或大于x的值)也满足(或不满足)条件。 - 这种单调性保证了可以通过二分缩小范围。
二、二分答案的适用场景
当问题符合以下特征时,可考虑使用二分答案:
- 问题要求求解「最大的满足条件的值」或「最小的满足条件的值」;
- 答案的范围可以明确界定(有明确的上下边界);
- 对于某个候选值
x,能快速判断其是否满足条件(即可以设计check函数)。
三、二分答案的基本步骤
- 确定答案范围:设定左边界
l和右边界r(即可能的答案最小值和最大值); - 设计
check函数:判断候选值x是否满足问题的条件; - 二分查找最优解:
- 计算中间值
mid = (l + r) / 2; - 用
check(mid)判断mid是否满足条件; - 根据判断结果调整
l或r,缩小范围; - 重复上述过程,直到
l > r,此时记录的最优解即为答案。
- 计算中间值
四、代码实例分析(木材切割问题)
以下代码解决的问题:
有n棵树,高度分别为a[1]~a[n],现需要砍伐树木,使砍伐后所有木材的总长度至少为m。求最高的砍伐高度(即砍伐后每棵树的高度为x,高于x的部分被砍伐,求最大的x使得总砍伐量≥m)。
代码逐段解析
#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,m,a[1000010];
- 定义变量:
n为树的数量,m为需要的木材总长度,a数组存储每棵树的高度。
bool check(int x){//判断砍伐高度为x的时候 是否满足条件
int sum=0;
for(int i=1;i<=n;i++){
if(a[i]>x) sum+=a[i]-x;
}
return sum>=m;
}
check函数:核心是判断「砍伐高度为x时,总砍伐量是否≥m」。- 遍历每棵树,若树高
a[i] > x,则砍伐部分为a[i]-x,累加总砍伐量sum; - 若
sum ≥ m,返回true(x是可行的砍伐高度),否则返回false。
- 遍历每棵树,若树高
signed main(){
cin>>n>>m;
for(int i=1;i<=n;i++) cin>>a[i];
int l=1,r=1e9,ans; // 步骤1:确定答案范围
while(l<=r){ // 步骤3:二分查找
int mid=(l+r)>>1; // 等价于mid=(l+r)/2,避免溢出
if(check(mid)){ // 若mid满足条件
ans=mid; // 记录当前mid为候选最优解
l=mid+1; // 尝试更大的x(因为要找最大可行值)
}
else{ // 若mid不满足条件
r=mid-1; // 只能尝试更小的x
}
}
cout<<ans;
return 0;
}
- 主函数逻辑:
- 输入数据:读入树的数量
n、需要的木材m和每棵树的高度; - 设定范围:
l=1(最小可能高度),r=1e9(最大可能高度,可根据实际数据调整); - 二分过程:
- 计算中间值
mid; - 若
check(mid)为true:说明mid是可行的,但可能有更大的可行值,因此更新ans=mid,并将左边界右移(l=mid+1); - 若
check(mid)为false:说明mid不可行,需要更小的高度,因此将右边界左移(r=mid-1);
- 计算中间值
- 输出结果:循环结束后,
ans即为最大的可行砍伐高度。
- 输入数据:读入树的数量
五、关键注意点
-
单调性分析:本例中,
x越大,总砍伐量越少(单调性)。因此:- 若
x可行(check(x)=true),则所有小于x的值也可行,但我们要找最大的x,因此需要尝试更大的范围; - 若
x不可行(check(x)=false),则所有大于x的值更不可行,只能尝试更小的范围。
- 若
-
边界设置:
l和r的初始值需覆盖所有可能的答案(如本例中树木高度不可能为负,故l=1,r设为较大值)。 -
check函数效率:check函数的时间复杂度直接影响整体效率(本例中check为O(n),二分过程为O(log(max_a)),总复杂度为O(n log max_a),高效可行)。
六、总结
二分答案是解决「最优解问题」的高效方法,核心在于:
- 识别问题的单调性;
- 设计正确的
check函数; - 合理设置边界并执行二分查找。
通过多练习类似「木材切割」「最小时间」「最大容量」等问题,可以快速掌握二分答案的应用。