基本技巧(长期更新)
贪心
分治
二分
看到使最大值最小或者使最小值最大时都可以尝试上二分。
注意二分的问题要有单调性(在某一点之前都不满足,之后都满足)。
二分的 种写法
虽然令人难蚌,但二分有很多种写法,尽量都了解/掌握。
虽然说是很多种写法但还是就记录主流的吧QwQ
第一种:
个人认为最好写最好理解的一种
在单调递增序列
区间为
\\初始化l,r,并且ans=-1
while(l<=r){
int mid=l+r>>1;
if(a[mid]>=x) ans=mid,r=mid-1;//l=mid+1或者r=mid-1,根据题目和自己写的check判断。
else l=mid+1;
}
\\最后得到的ans即为答案,如果ans=-1则无解
第二种:
分为两套。答案都处于
- 在单调递增序列
中查找第一个大于等于 的值的位置( 或 的后继)。
while(l<r){
int mid=l+r>>1;
if(a[mid]>=x) r=mid;
else l=mid+1;
}
//最终l即为答案
- 在单调递增序列
中查找最后一个小于等于 的值的位置( 或 的前驱)。
while(l<r){
int mid=l+r+1>>1;
if(a[mid]<=x) l=mid;
else r=mid-1;
}
//最终l即为答案
总结一下两种形式:
-
缩小范围时,
,取中间值时, 。 -
缩小范围时,
,取中间值时, 。
接下来说明
假如
注意必须采用
特别的作用:我们观察一下,
终止时
实数域上二分
比整数域上的简单多了
首先要确定二分精度
一般来说,要保留
注意此时就只能使用
while(l+eps<r){
double mid=(l+r)/2;
if(check(mid)) l=mid;
else r=mid;
}
也可以用固定循环次数的二分,精度通常比设置
for(int i=0;i<100;++i){
double mid=(l+r)/2;
if(check(mid)) l=mid;
else r=mid;
}
二分的重要思想
最优化问题也能抽象为函数。
要二分答案,函数就要有单调性,即在一边都不合法,一边都合法。
把求最优解的问题转化为判定是否能构造出解为
wqs二分
去看DP优化。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通