47. Распределение загрузки на грузовики #
Условие задачи:
🔥 Реализовать метод calcTrucks
, который принимает массив весов грузов, количество грузовиков и их максимальную грузоподъемность, распределяет грузы по грузовикам так, чтобы максимально загрузить их, и возвращает суммарную недогруженность (общая свободная емкость).
/**
* @param weights массив весов грузов
* @param trucksCount количество грузовиков
* @param truckMaxCapacity максимальная грузоподъемность одного грузовика
* @return суммарная недогруженность (truckCount*truckMaxCapacity - суммарный вес размещённых грузов)
*/
private int calcTrucks(int[] weights, int trucksCount, int truckMaxCapacity) {
// TODO
}
Спойлеры к решению
Подсказки
💡 Эту задачу можно свести к многоконтейнерному упаковочному (bin packing) с целью минимизации пустого места.
💡 Один из эффективных эвристических методов — Best Fit Decreasing:
Сначала отсортировать грузы по убыванию веса.
Затем для каждого груза найти тот грузовик (контейнер), где после загрузки останется минимальное, но неотрицательное, свободное место.
💡 Если груз никак не помещается ни в один имеющийся контейнер, его можно пропустить (или считать недогруженным целиком).
Решение
import java.util.Arrays;
public class TruckLoader {
public static int calcTrucks(int[] weights, int trucksCount, int truckMaxCapacity) {
// 1. Сортировка грузов по убыванию для Best Fit Decreasing
Arrays.sort(weights);
// переворачиваем массив
for (int i = 0, j = weights.length - 1; i < j; i++, j--) {
int tmp = weights[i];
weights[i] = weights[j];
weights[j] = tmp;
}
// 2. Массив текущей загрузки каждого грузовика
int[] load = new int[trucksCount];
// инициализируем нулями
// 3. Для каждого груза ищем "best fit"
for (int w : weights) {
int bestIndex = -1;
int minRemaining = Integer.MAX_VALUE;
for (int i = 0; i < trucksCount; i++) {
int remaining = truckMaxCapacity - (load[i] + w);
if (remaining >= 0 && remaining < minRemaining) {
minRemaining = remaining;
bestIndex = i;
}
}
if (bestIndex >= 0) {
load[bestIndex] += w;
}
// иначе груз не помещается никуда — пропускаем
}
// 4. Считаем суммарную недогруженность
int totalFree = 0;
for (int i = 0; i < trucksCount; i++) {
totalFree += (truckMaxCapacity - load[i]);
}
return totalFree;
}
public static void main(String[] args) {
System.out.println(calcTrucks(new int[]{10, 100, 20, 30, 40, 10}, 4, 100)); // 90
System.out.println(calcTrucks(new int[]{10, 100, 20, 30, 40}, 4, 100)); // 0
}
}
📌 Что важно помнить:
✅ Best Fit Decreasing — простая и быстрая эвристика, дающая хорошее приближение к оптимуму для bin-packing.
✅ Сначала сортируем грузы по убыванию, затем размещаем каждый в самый подходящий контейнер, минимизируя остаток.
✅ Вычисляем суммарное свободное место по всем грузовикам и возвращаем его как меру недогрузки.