当前位置:首页 > 算法 > 正文内容

【算法】二分法—最大化平均值问题简单总结

亿万年的星光3年前 (2022-03-26)算法3219

0.前言

通过几道题目 切割钢管木材加工切割绳子均分蛋糕 四道题,尝试了二分法中最大化平均值问题。

然后,下面进行简单的对比和总结。


1.简单总结

while(l < r){
        int mid = (l + r) >> 1;// 二分查找
		int cnt = 0; 
        for(int i=0;i<n;i++){
            cnt += a[i] / mid;
        }
        if(cnt >= k){ 
            //那么这个mid是可行的,我们就可以扩大左边界值
            l = mid + 1;
        }else{
            r = mid;
            //否则的话,这个mid就是太高了,就可以把右边界缩小
        }
    }


写法2:

while(l <r-1){
        int mid = (l + r) >> 1;// 二分查找
		int cnt = 0; 
        for(int i=0;i<n;i++){
            cnt += a[i] / mid;
        }
        if(cnt >= k){ 
            //那么这个mid是可行的,我们就可以扩大左边界值
            l = mid;
        }else{
            r = mid;
            //否则的话,这个mid就是太高了,就可以把右边界缩小
        }
    }

写法2进行简单变换还可以写成:

while(l+1 <r){
        int mid = (l + r) >> 1;// 二分查找
		int cnt = 0; 
        for(int i=0;i<n;i++){
            cnt += a[i] / mid;
        }
        if(cnt >= k){ 
            //那么这个mid是可行的,我们就可以扩大左边界值
            l = mid;
        }else{
            r = mid;
            //否则的话,这个mid就是太高了,就可以把右边界缩小
        }
    }


如果出现小数,那么可以这么写:

while ((right-left)>1e-4) 
{
	mid=(left+right)/2;
	for (i = 0; i < n; i++)
		num += (int)(a[i] / x);
	if(sum>=k)
		left=mid;
	else
		right=mid;
}
//1e-4=0.0001
//等价于下面这样: 
while (left+1e-4<right) 
{
	mid=(left+right)/2;
	for (i = 0; i < n; i++)
		num += (int)(a[i] / x);
	if(sum>=k)
		left=mid;
	else
		right=mid;
}


注意: 这类题目的最大值一般通过循环求出,一般单体的最大值作为初始右端点,或者单体和的最大值作为右端点。


然后,有一类写法带等号

变形:(带等号的左右端点都要变)

while(l <= r){
        int mid = (l + r) >> 1;// 二分查找
		int cnt = 0; 
        for(int i=0;i<n;i++){
            cnt += a[i] / mid;
        }
        if(cnt >= k){ 
            //那么这个mid是可行的,我们就可以扩大左边界值
            l = mid + 1;
        }else{
            r = mid - 1;
            //否则的话,这个mid就是太高了,就可以把右边界缩小
        }
    }






2.题目扩展

可以有单一的线条类型,变成复杂的面积、体积等类型。比如均分蛋糕


3.说明

上述过程,我们大部分都是在取左端点,其实可以取右端点。比如下面这两个代码模板:

取左端点:

while (l < r) {
	int mid = (l + r) / 2;
	if (judge(mid))
		r = mid;//judge()函数判断是否在范围内,为布尔型
	else
		l  = mid + 1;//避免死循环
}
return l;

取右端点:

while (l < r) {
	int mid = (l + r + 1) / 2;//+1避免死循环
	if (judge(mid))  
		l = mid;
	else  
		r = mid - 1;
}
return 1;


4.本质

二分:自定义某一性质,让区间的左边元素均不满足,右边元素均满足或者反过来。

扫描二维码推送至手机访问。

版权声明:本文由青少年编程知识记录发布,如需转载请注明出处。

分享给朋友:

相关文章

【算法】动态规划(二)——数字三角形问题

【算法】动态规划(二)——数字三角形问题

1.问题描述及状态定义数字三角形问题:有一个非负整数组成的三角形,第一行只有一个数,除了最下行之外每个数字的坐下方和右下方各有一个数。如下图所示:从第一行开的数开始走,每次可以往下或右走一格,直到走到...

【算法】博弈论——取石子游戏

【题目描述】有两堆石子,数量任意,可以不同。游戏开始由两个人轮流取石子。游戏规定,每次有两种不同的取法,一是可以在任意的一堆中取走任意多的石子;二是可以在两堆中同时取走相同数量的石子。最后把石子全部取...

【算法】最小重量机器设计

【题目描述】设某一机器由n个部件组成,每一种部件都可以从m个不同的供应商处购得。设Wij 是 从供应商j处购得的部件i的重量,Cij 是相应的价格。 试设计一个算法,给出总价格不超...

【排序】----冒泡排序

【排序】----冒泡排序

1.基本思想两个数比较大小,较大的数下沉,较小的数冒起来。2.过程·每次比较相邻的两个数,如果第二个数小,就交换位置。(升序或降序)·然后两两比较,一直到比较最后的数据。最终最小(大)数被交换到开始(...

【算法】最大子段和

【算法】最大子段和

【题目描述】给出一个长度位n的序列a,选出其中连续且非空的一段使得这段和最大【输入描述】第一行是一个整数,表示序列的长度n。第二行有n个整数,第i个整数表示序列的第i个数字ai【输出描述】输出一行一个...

【算法】前缀和与差分(2)一 一维数组差分

【算法】前缀和与差分(2)一 一维数组差分

一、差分:一维数组的差分可看作是一维数组前缀和的逆运算。二、差分数组首先给定一个原数组a:   a[1]、a[2]、a[3]、......然后构造一个数组b: b[1]、b[2]、...