二分练习题——奶牛晒衣服

奶牛晒衣服

题目分析

这里出现了"弄干所有衣服的最小时间",那么可以考虑用二分去做。

第一阶段二段性分析

假设当前需要耗费的时间为mid分钟,如果mid分钟内可以烘干这些衣服,那么我们可以确定右边界大于mid的区间一定也可以。但是此时我需要找的是最短时间,那么mid一定比大于mid的值更小,所以大于mid的值我就不用管了,也就是我可以确定我能够舍弃掉mid右边的值。我还想要确定比mid更小的值是否也满足条件,所以我要在mid的左边继续二分。

java 复制代码
if(check(mid)) {r = mid;}//因为mid是符合条件的,所以我要留着它,而不是r=mid-1

假设当前需要耗费的时间为mid分钟,如果mid分钟内不可以烘干这些衣服,那么我们可以确定右边界小于mid的区间一定也不可以。所以小于mid的值我就不用管了,也就是我可以确定我能够舍弃掉mid左边的值。我还想要找比mid更大的值是否可以满足条件,所以我要在mid的右边继续二分。

java 复制代码
else {l = mid + 1;}//因为mid是不符合条件的,所以我不要留着它,而不是l=mid

综上该题满足二段性,可以用二分,二分的板子就不说了,接下来说一下check函数如何写。

第二阶段写check函数

check(mid)要实现的作用是检查能否在mid分钟内烘干这些衣服。对于一个衣服的湿度wi,如果wi/a大于mid(注意这里要采用函数实现上取整的话,应该使用double类型,所以在java里使用函数实现上取整时,用 a ∗ 1.0 a*1.0 a∗1.0将整数类型转化为浮点数类型),就需要使用烘干机,使用的时间是(ai-mid*a)/b,a是自然烘干每分钟可以减少的湿度,b是烘干机烘干每分钟额外减少的湿度。因为烘干衣服不足1分钟也要按一分钟算,所以这里要上取整。

java

java 复制代码
static boolean check(int mid){
    long s = 0;
    for (int i = 0; i < n; i++) {
        if (Math.ceil(w[i]/(a*1.0))>mid){
            s += Math.ceil((w[i]-a*mid)/(b*1.0));
        }
    }
    return s <= mid;
}

c++

cpp 复制代码
//这里的w[i]+a-1和w[i] - a * x + b - 1,即比正常多出来的+a-1和+b-1都是为了实现上取整。
bool check(int x){
	long sum = 0;
	for (int i = 0; i < n; i ++){
		if ((w[i]+a-1) / a <= x)
			continue;
        sum += (w[i] - a * x + b - 1) / b;
	}
	if (sum <= x)
		return true;
	else return false;
}

第三阶段二分范围确定

烘干的时间最长就是不使用烘干机,自然风干需要ai分钟,而ai最大是1e9,所以l=0,r=1e9。

注意一个特殊情况,如果k=1,那么其实烘干机有和没有都一样,自然风干所需要的时间就是所有衣服中最大的湿度。

题目代码

cpp 复制代码
#include <iostream>
#include <stdbool.h>
#define N 500010

int n, a, b;
int w[N];

bool check(int x){
	long sum = 0;
	for (int i = 0; i < n; i ++){
		if ((w[i]+a-1) / a <= x)
			continue;
        sum += (w[i] - a * x + b - 1) / b;
	}
	if (sum <= x)
		return true;
	else return false;
}
int main(){
	scanf("%d%d%d",&n, &a, &b);
	for (int i = 0; i < n; i ++){
		scanf("%d", &w[i]);
	}
	int l = 0;
	int r = 5e5 + 5;
	while (l < r){
		int mid = (l + r) / 2;
		if (check(mid))
			r = mid;
		else
			l = mid + 1;
	}
	printf("%d", l);
	return 0;
}
java 复制代码
import java.util.Scanner;
public class Main{
    static int a;
    static  int b;
    static int n;
    static int[] w;
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        n = scan.nextInt();
        w = new int[n];
        a = scan.nextInt();
        b = scan.nextInt();
//       int max = a+b;
        for (int i = 0; i <n; i++) {
                w[i]= scan.nextInt();
//            max= Math.max(max, w[i]);
        }
        int l = 0;
        int r = 500005;
        while (l<r){
            int mid=(l+r)/2;
            if(check(mid)){
                r=mid;
            }else {
                l=mid+1;
            }
        }
        System.out.println(l);
    }
    static boolean check(int mid){
        long s = 0;
        for (int i = 0; i < n; i++) {
            if (Math.ceil(w[i]/(a*1.0))>mid){
                s += Math.ceil((w[i]-a*mid)/(b*1.0));
            }
        }
        return s <= mid;
    }
}
相关推荐
郑州光合科技余经理几秒前
海外版外卖加盟:总站与分站配送规则怎么分开管
java·开发语言·前端·后端·uni-app·php·ai编程
2601_962071572 分钟前
类变量和全局变量的生命周期有什么区别?
java·开发语言·jvm
code2cat13 分钟前
Java进阶篇之AtomicReference:一次替换引用,读到一份完整状态
java·并发编程·不可变对象·atomicreference
专业程序开发源16 分钟前
springboot简历管理系统81389-计算机课程设计、毕业设计
java·vue.js·spring boot·后端·spring·php·课程设计
Wang's Blog17 分钟前
Java 项目实战: 外卖平台优化-前后端分离开发模式与工程拆分
java·开发语言
2601_960356381 小时前
2027校招采购岗解析:数学基础如何迁移到需求预测、成本与供应商分析
人工智能·算法
h_a_o777oah1 小时前
【树论】树链剖分:将树形结构转化为线性结构以处理树上路径问题(洛谷 P3384 附C++代码模板)
数据结构·算法·线段树·acm·树链剖分·树论·重链剖分
HEJOO91 小时前
指针的算术运算详解
java·数据结构·算法
sunshine22 girl1 小时前
Java学习六 Java常见API-2--String-3-字符串的截取替换和其他方法
java·开发语言·学习
Coder-magician1 小时前
《代码随想录》刷题打卡day47:并查集-part01
数据结构·算法·图论