题目描述
火车站附近的货物中转站负责将到站货物运往仓库,小明在中转站负责调度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 <iostream>
#include <vector>
#include <algorithm>
using namespace std;
bool check(int index, vector<int>& weights, vector<int>& 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<int>& 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<int> 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<int>& goods, vector<int>& types, int k) {
vector<int> 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<int> 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<Integer> dry = new ArrayList<>();
List<Integer> 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<int>& weights, vector<int>& buckets, int limit):这个函数是一个递归函数,用于检查是否可以将重量为weights中的元素分配到buckets中的k个桶中,使得每个桶的总重量不超过limit。参数index表示检查weights中的第index个元素是否可以分配到桶中。如果可以,函数会递归检查下一个元素是否可以分配,直到所有元素都被检查完毕。如果所有元素都可以被分配,则返回true;否则返回false。
int getMinMaxWeight(vector<int>& weights, int k):这个函数用于查找可以将重量为weights中的元素分配到k个桶中的最小桶容量。它使用二分查找算法来查找最小的满足条件的桶容量。在每个迭代中,函数首先计算中间的桶容量mid_weight,然后使用check()函数检查是否可以将所有元素分配到k个桶中,使得每个桶的总重量不超过mid_weight。如果可以,函数继续查找更小的桶容量;否则,函数查找更大的桶容量。
int getResult(int n, vector<int>& goods, vector<int>& types, int k):。它将干货和湿货分别放入两个向量中,然后找到能够分配干货和湿货的最小桶容量。最后,函数返回干货和湿货最小桶容量的最大值。