二分的思路:二分其实是一种搜索,根据已有的数据来搜索出一个满足题意要求的数据,
最初级的二分是在一个有序数组中查找一个设定的值
但是二分搜索有很多种应用,在一些情况下没有必要先对数据进行排序
例如需要对数据进行划分时,只需要计算出data[i]/mid的值就ok
目前对二分的理解还是比较浅薄,先上模板吧
一、事前准备
int n,l=INF,r=-1,mid;
ll sum=0;
cin>>n;
for(int i=0;i<n;i++){
cin>>a[i];
l=min(l,a[i]);
r=max(r,a[i]);
}
在二分之前需要对左右值进行初始化,以保证数据的范围符合题意,如ans值在数据范围中,则根据需要进行最大最小值的储存
二、二分模板
二分的模板大概有两种:主要是体现在while的判断框内
1.边界二分(整数)
while(l<=r){
sum=0;
mid=(l+r)/2;
for(int i=0;i<n;i++){
if(a[i]>mid)sum+=(a[i]-mid)/2;
else sum+=a[i]-mid;
}
if(sum>=0)l=mid+1;
else r=mid-1;
// cout<<l<<" "<<r<<endl;
}
cout<<r<<endl;
这种二分的使用范围主要是整数二分,每次都将l和r集中在答案的两侧,偏移量为1,
当r或l越过边界时,r变为左边界,也就是符合题意的最大值
2.精度二分(浮点数)
while(r-l>1e-6){
mid=(l+r)/2;
sum=0;
for(int i=0;i<cn;i++){
sum+=(int)(cake[i]/mid);
}
if(sum>=peo)l=mid;
else r=mid;
}
精度二分是要适用于浮点数的二分,它的使用是方便于控制精度,偏移量为0
当循环结束时,答案达到精度要求,此时l为左边界,则为符合题意的最大值
注意:如果使用精度二分,l,r,mid均为浮点数
三、注意事项
1、在用到π时,一般将pi设置为acos(-1.0),精度较高
2、在精度计算中,直接用%.(x)lf 时会四舍五入,如果需要舍弃小数,则使用如下算法
(例:两位小数时)
ans=floor(mid*100)/100;
先写到这,以后再补充