华为OD机试-最少交付时间-二分查找(Java 2025A卷 200分)

在这里插入图片描述

import java.util.*;

/**
 * @version Ver 1.0
 * @date 2025/6/19
 * @description
 */
public class MinTime {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        // 读取工作量和员工数
        String[] workloadStr = scanner.nextLine().split(" ");
        int[] workloads = Arrays.stream(workloadStr).mapToInt(Integer::parseInt).toArray();
        int numEmployees = Integer.parseInt(scanner.nextLine());

        // 计算最短完成时间
        int minDays = calculateMinimumDays(workloads, numEmployees);
        System.out.println(minDays);
		// 二分
        int minDays2 = solve2(workloads, numEmployees);
        System.out.println(minDays2);
    }

    private static int solve2(int[] workloads, int numEmployees) {
        int left = Arrays.stream(workloads).max().getAsInt();
        int right = Arrays.stream(workloads).sum();
        while(left < right){
            int mid = left + (right - left) / 2;
            if(canReach(workloads,numEmployees,mid)){
                right = mid;
            }else{
                left = mid+1;
            }
        }
        return left;
    }

    private static boolean canReach(int[] workloads, int numEmployees, int mid) {
        Arrays.sort(workloads);
        //存储每个工人的工作量
        int[] workers = new int[numEmployees];
        for(int i = workloads.length - 1; i>=0;i--){
            // 工作量最小的员工索引
            int minEmployeeIndex = 0;
            for(int j=1;j<numEmployees;j++){
                if(workers[j] < workers[minEmployeeIndex]){
                    //更新工作量最小的员工索引
                    minEmployeeIndex = j;
                }
            }
            workers[minEmployeeIndex] += workloads[i];
            if(workers[minEmployeeIndex] > mid){
                return false;
            }
        }
        return true;
    }

    private static int calculateMinimumDays(int[] workloads, int numEmployees) {
        // 将任务按照工作量从大到小排序
        Arrays.sort(workloads);
        // 初始化员工工作天数数组
        int[] employeeLoad = new int[numEmployees];

        // 从最大工作量任务开始分配
        for (int i = workloads.length - 1; i >= 0; i--) {
            int minLoadIndex = 0;
            // 找到当前工作量最小的员工
            for (int j = 1; j < numEmployees; j++) {
                if (employeeLoad[j] < employeeLoad[minLoadIndex]) {
                    minLoadIndex = j;
                }
            }
            // 分配任务给该员工
            employeeLoad[minLoadIndex] += workloads[i];
        }

        // 找出最大的工作量,即为完成所有任务的最少天数
        int maxDays = 0;
        for (int load : employeeLoad) {
            maxDays = Math.max(maxDays, load);
        }
        return maxDays;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值