【HUAWEI OJ 题库】业务负载分配

题目描述

现有一个服务器集群(服务器数量为 serverNum),和一批不同类型的任务(用数组 task表示,下标表示任务类型,值为任务数量)。

现需要把这批任务都分配到集群的服务器上,分配规则如下:

  • 应业务安全要求,不同类型的任务不能分配到同一台服务器上
  • 一种类型的多个任务可以分配在多台服务器上

「负载」定义为某台服务器所分配的任务个数,无任务的服务器负载为0。
「最高负载」定义为所有服务器中负载的最大值。

请你制定分配方案,使得分配后「最高负载」的值最小,并返回该最小值。

解答要求

时间限制:1000ms, 内存限制:256MB

输入

第一行一个整数,表示集群中服务器的数量 serverNum,1 ≤ serverNum ≤ 10^9
第二行一个整数,表示这批任务有 taskTypeNum 种类型,1 ≤ taskTypeNum ≤ 100000,且 taskTypeNum <= serverNum
第三行输入 taskTypeNum 个整数,为 task 数组,表示这批任务,1 ≤ task[i] ≤ 10^9

输出

一个整数,表示「最高负载」的最小值

样例

输入样例 1 复制

5
2
7 4

输出样例 1

3

提示样例 1

类型 0 的任务有 7 个,可表示为 0000000;类型 1 的任务有 4 个,可表示为 1111 :

  • 按 11、11、00、00、000 或 1、111、00、00、000 分配给 5 台服务器,该分配方案的「最高负载」值为 3,是最小的
  • 其它方案的「最高负载」值都更大,例如 11、11、0000、000 的「最高负载」为 4

说明:
任务0和任务1不能分配到同一台服务器上。
一次性制定分配方案,不存在二次分配。

输入样例 2

8
5
101 1 1 20 40

输出样例 2

34

提示样例 2

  • 如果「最高负载」为 1,需要的服务器台数为 101 + 1 + 1 + 20 + 40 = 163,超过了给定的服务器数量。因此需要尝试更大的「最高负载」值
  • 如果「最高负载」为 33, 需要的服务器台数为 9
  • 如果「最高负载」为 34, 需要的服务器台数为 8
  • 如果「最高负载」为 35, 需要的服务器台数也为 8
  • 如果「最高负载」为 40, 需要的服务器台数为 7,服务器有浪费
  • 如果「最高负载」为 101, 需要的服务器台数为 5,服务器有更多浪费

所以「最高负载」值最小为 34

温馨提醒:注意计算中的过程值溢出

提示

温馨提醒:纯暴力解法无法通过所有用例

编码实现(Java)

    public static void main(String[] args) {
        System.out.println(findMinLoad(5, new int[]{7, 4}));
        System.out.println(findMinLoad(8, new int[]{101, 1, 1, 20, 40}));
    }

    private static int findMinLoad(int serverNum, int[] tasks) {
        int left = 1; // Minimum load
        int right = Arrays.stream(tasks).max().getAsInt() * serverNum; // Maximum load

        while (left < right) {
            int mid = left + (right - left) / 2;

            if (canAssign(tasks, serverNum, mid)) {
                right = mid;
            } else {
                left = mid + 1;
            }
        }

        return left;
    }

    private static boolean canAssign(int[] tasks, int serverNum, int maxLoad) {
        int requiredServers = 0;

        for (int task : tasks) {
            requiredServers += (int) Math.ceil((double) task / maxLoad);
        }

        return requiredServers <= serverNum;
    }

输出结果

3
34

Process finished with exit code 0
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值