【2023.3华为OD机试】 统一限载货物数最小值 (Java & C++& Python)

题目描述

火车站附近的货物中转站负责将到站货物运往仓库,小明在中转站负责调度2K辆中转车(K辆干货中转车,K辆湿货中转车)。

货物由不同供货商从各地发来,各地的货物是依次进站,然后小明按照卸货顺序依次装货到中转车,一个供货商的货只能装到一辆车上,不能拆装,但是一辆车可以装多家供货商的货;

中转车的限载货物量由小明统一指定,在完成货物中转的前提下,请问中转车的统一限载货物数最小值为多少。

输入描述

  • 第一行 length 表示供货商数量 1 <= length <= 10^4
  • 第二行 goods 表示供货数数组 1 <= goods[i] <= 10^4
  • 第三行 types表示对应货物类型,types[i]等于0或者1,其中0代表干货,1代表湿货
  • 第四行 k表示单类中转车数量 1 <= k <= goods.length

输出描述

运行结果输出一个整数,表示中转车统一限载货物数

备注

中转车最多跑一趟仓库

用例

输入

4
3 2 6 3
0 1 1 0
2

输出

6

说明

货物1和货物4为干货,由2辆干货中转车中转,每辆车运输一个货物,限载为3

货物2和货物3为湿货,由2辆湿货中转车中转,每辆车运输一个货物,限载为6

这样中转车统一限载货物数可以设置为6(干货车和湿货车限载最大值),是最小的取值

输入

4
3 2 6 8
0 1 1 1
1

输出

16

说明

货物1为干货,由1辆干货中转车中转,限载为3

货物2、货物3、货物4为湿货,由1辆湿货中转车中转,限载为16

这样中转车统一限载货物数可以设置为16(干货车和湿货车限载最大值),是最小的取值

C++

#include 
#include 
#include 

using namespace std;
bool check(int index, vector& weights, vector& buckets, int limit) {
    if (index == weights.size()) {
        return true;
    }

    int select = weights[index];
    for (int i = 0; i < buckets.size(); i++) {
        if (buckets[i] + select <= limit) {
            buckets[i] += select;
            if (check(index + 1, weights, buckets, limit)) {
                return true;
            }
            buckets[i] -= select;
            if (buckets[i] == 0) {
                return false;
            }
        }
    }

    return false;
}

int getMinMaxWeight(vector& weights, int k) {
    int n = weights.size();

    if (n <= k) {
        return *max_element(weights.begin(), weights.end());
    }

    sort(weights.begin(), weights.end(), [](int a, int b){ return a > b; });

    int min_weight = weights[0];
    int max_weight = accumulate(weights.begin(), weights.end(), 0);

    while (min_weight < max_weight) {
        int mid_weight = (min_weight + max_weight) >> 1;

        vector buckets(k, 0);
        int index = 0;
        while (index < n && check(index, weights, buckets, mid_weight)) {
            index++;
        }

        if (index == n) {
            max_weight = mid_weight;
        } else {
            min_weight = mid_weight + 1;
        }
    }

    return min_weight;
}


int getResult(int n, vector& goods, vector& types, int k) {
    vector dry, wet;
    for (int i = 0; i < n; i++) {
        if (types[i] == 0) {
            dry.push_back(goods[i]);
        } else {
            wet.push_back(goods[i]);
        }
    }

    return max(getMinMaxWeight(dry, k), getMinMaxWeight(wet, k));
}

int main() {
    int n, k;
    cin >> n;

    vector goods(n), types(n);
    for (int i = 0; i < n; i++) {
        cin >> goods[i];
    }
    for (int i = 0; i < n; i++) {
        cin >> types[i];
    }
    cin >> k;

    cout << getResult(n, goods, types, k) << endl;

    return 0;
}

python

def check(index, weights, buckets, limit):
    if index == len(weights):
        return True

    select = weights[index]
    for i in range(len(buckets)):
        if buckets[i] + select <= limit:
            buckets[i] += select
            if check(index + 1, weights, buckets, limit):
                return True
            buckets[i] -= select
            if buckets[i] == 0:
                return False

    return False


def getMinMaxWeight(weights, k):
    n = len(weights)

    if n <= k:
        return max(weights)

    weights.sort(reverse=True)

    min_weight = weights[0]
    max_weight = sum(weights)

    while min_weight < max_weight:
        mid_weight = (min_weight + max_weight) >> 1

        buckets = [0] * k
        index = 0
        while index < n and check(index, weights, buckets, mid_weight):
            index += 1

        if index == n:
            max_weight = mid_weight
        else:
            min_weight = mid_weight + 1

    return min_weight


def getResult(n, goods, types, k):
    dry, wet = [], []
    for i in range(n):
        if types[i] == 0:
            dry.append(goods[i])
        else:
            wet.append(goods[i])

    return max(getMinMaxWeight(dry, k), getMinMaxWeight(wet, k))


if __name__ == '__main__':
    n = int(input())
    goods = list(map(int, input().split()))
    types = list(map(int, input().split()))
    k = int(input())

    print(getResult(n, goods, types, k))

JAVA

import java.util.*;

class t2 {
    static boolean check(int index, int[] weights, int[] buckets, int limit) {
        if (index == weights.length) {
            return true;
        }

        int select = weights[index];
        for (int i = 0; i < buckets.length; i++) {
            if (buckets[i] + select <= limit) {
                buckets[i] += select;
                if (check(index + 1, weights, buckets, limit)) {
                    return true;
                }
                buckets[i] -= select;
                if (buckets[i] == 0) {
                    return false;
                }
            }
        }

        return false;
    }

    static int getMinMaxWeight(int[] weights, int k) {
        int n = weights.length;

        if (n <= k) {
            int maxWeight = Integer.MIN_VALUE;
            for (int weight : weights) {
                maxWeight = Math.max(maxWeight, weight);
            }
            return maxWeight;
        }

        Arrays.sort(weights);
        int minWeight = weights[0];
        int maxWeight = Arrays.stream(weights).sum();

        while (minWeight < maxWeight) {
            int midWeight = (minWeight + maxWeight) >> 1;

            int[] buckets = new int[k];
            int index = 0;
            while (index < n && check(index, weights, buckets, midWeight)) {
                index++;
            }

            if (index == n) {
                maxWeight = midWeight;
            } else {
                minWeight = midWeight + 1;
            }
        }

        return minWeight;
    }

    static int getResult(int n, int[] goods, int[] types, int k) {
        List dry = new ArrayList<>();
        List wet = new ArrayList<>();
        for (int i = 0; i < n; i++) {
            if (types[i] == 0) {
                dry.add(goods[i]);
            } else {
                wet.add(goods[i]);
            }
        }

        return Math.max(getMinMaxWeight(dry.stream().mapToInt(i -> i).toArray(), k),
                getMinMaxWeight(wet.stream().mapToInt(i -> i).toArray(), k));
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        int[] goods = new int[n];
        int[] types = new int[n];
        for (int i = 0; i < n; i++) {
            goods[i] = scanner.nextInt();
        }
        for (int i = 0; i < n; i++) {
            types[i] = scanner.nextInt();
        }
        int k = scanner.nextInt();

        System.out.println(getResult(n, goods, types, k));
    }
}

分割线

bool check(int index, vector& weights, vector& buckets, int limit):这个函数是一个递归函数,用于检查是否可以将重量为weights中的元素分配到buckets中的k个桶中,使得每个桶的总重量不超过limit。参数index表示检查weights中的第index个元素是否可以分配到桶中。如果可以,函数会递归检查下一个元素是否可以分配,直到所有元素都被检查完毕。如果所有元素都可以被分配,则返回true;否则返回false。
int getMinMaxWeight(vector& weights, int k):这个函数用于查找可以将重量为weights中的元素分配到k个桶中的最小桶容量。它使用二分查找算法来查找最小的满足条件的桶容量。在每个迭代中,函数首先计算中间的桶容量mid_weight,然后使用check()函数检查是否可以将所有元素分配到k个桶中,使得每个桶的总重量不超过mid_weight。如果可以,函数继续查找更小的桶容量;否则,函数查找更大的桶容量。
int getResult(int n, vector& goods, vector& types, int k):。它将干货和湿货分别放入两个向量中,然后找到能够分配干货和湿货的最小桶容量。最后,函数返回干货和湿货最小桶容量的最大值。

你可能感兴趣的:(2023华为OD机试题,c++,python,开发语言,算法)