План курса / Все задачи / Алгоритмы и структуры данных
Поиск минимальной грузоподъемности
средне
Имеется массив weights, представляющий веса коробок, и число days, обозначающее количество дней, за которое все коробки должны быть перевезены.
Необходимо найти минимальную грузоподъёмность грузовика, чтобы перевезти все коробки в указаном порядке в weights за days дней.
Пример 1:
Ввод: weights = [1,2,3,4,5,6,7,8,9,10], days = 5
Вывод: 15
Пример 2:
Ввод: weights = [3,2,2,4,1,4,3], days = 3
Вывод: 7
Ограничения:
len(weights) >= 1
weights[i] >= 1
days >= 1
using System;
using System.Collections.Generic;
public class Solution {
// Возвращает true, если можно за days дней разгрузить weights с
// максимальной вместимостью maxLoad, и false в обратном случае
public static bool IsValidCapacity(List<int> weights, int days, int maxLoad) {
int currWeight = 0;
int daysCount = 1;
foreach (int weight in weights) {
if (currWeight + weight <= maxLoad) {
currWeight += weight;
} else {
currWeight = weight;
daysCount += 1;
}
}
return daysCount <= days;
}
public static int FindShipCapacity(List<int> weights, int days) {
// maxWeight - максимальный вес одной посылки является
// минимальной возможной вместимостью
int maxWeight = int.MinValue;
int totalWeight = 0;
foreach (int weight in weights) {
if (weight > maxWeight) {
maxWeight = weight;
}
totalWeight += weight;
}
// ответ будет находится в правом указателе, поэтому
// l = maxWeight - 1, чтобы ответом могло быть минимальное
// допустимое значение для ответа: maxWeight
int l = maxWeight - 1, r = totalWeight;
while (r - l > 1) {
int m = (l + r) / 2;
if (!IsValidCapacity(weights, days, m)) {
l = m;
} else {
r = m;
}
}
return r;
}
}
#include <vector>
using namespace std;
// Возвращает true, если можно за days дней разгрузить weights с
// максимальной вместимостью maxLoad, и false в обратном случае
bool isValidCapacity(vector<int> weights, int days, int maxLoad) {
int currWeight = 0;
int daysCount = 1;
for (int weight : weights) {
if (currWeight + weight <= maxLoad) {
currWeight += weight;
} else {
currWeight = weight;
daysCount++;
}
}
return daysCount <= days;
}
int findShipCapacity(vector<int> weights, int days) {
// maxWeight - максимальный вес одной посылки является
// минимальной возможной вместимостью
int maxWeight = *max_element(weights.begin(), weights.end());
// totalWeight - общая сумма весов - это максимальное
// значение ответа
int totalWeight = accumulate(weights.begin(), weights.end(), 0);
// ответ будет находится в правом указателе, поэтому
// l = maxWeight - 1, чтобы ответом могло быть минимальное
// допустимое значение для ответа: maxWeight
int l = maxWeight - 1, r = totalWeight;
while (r - l > 1) {
int m = (l + r) / 2;
if (!isValidCapacity(weights, days, m)) {
l = m;
} else {
r = m;
}
}
return r;
}
package main
// Возвращает true, если можно за days дней разгрузить weights с
// максимальной вместимостью maxLoad, и false в обратном случае
func isValidCapacity(weights []int, days int, maxLoad int) bool {
currWeight := 0
daysCount := 1
for _, weight := range weights {
if currWeight+weight <= maxLoad {
currWeight += weight
} else {
currWeight = weight
daysCount++
}
}
return daysCount <= days
}
func findShipCapacity(weights []int, days int) int {
// maxWeight - максимальный вес одной посылки является
// минимальной возможной вместимостью
maxWeight := 0
// totalWeight - общая сумма весов - это максимальное
// значение ответа
totalWeight := 0
for _, weight := range weights {
if weight > maxWeight {
maxWeight = weight
}
totalWeight += weight
}
// ответ будет находится в правом указателе, поэтому
// l = maxWeight - 1, чтобы ответом могло быть минимальное
// допустимое значение для ответа: maxWeight
l, r := maxWeight-1, totalWeight
for r-l > 1 {
m := (l + r) / 2
if !isValidCapacity(weights, days, m) {
l = m
} else {
r = m
}
}
return r
}
import java.util.*;
public class Solution {
public Integer findShipCapacity(List<Integer> weights, Integer days) {
// maxWeight - максимальный вес одной посылки является
// минимальной возможной вместимостью
int maxWeight = Collections.max(weights);
// totalWeight - общая сумма весов - это максимальное
// значение ответа
int totalWeight = weights.stream().mapToInt(Integer::intValue).sum();
// ответ будет находится в правом указателе, поэтому
// l = maxWeight - 1, чтобы ответом могло быть минимальное
// допустимое значение для ответа: maxWeight
int l = maxWeight - 1, r = totalWeight;
while (r - l > 1) {
int m = (l + r) / 2;
if (!isValidCapacity(weights, days, m)) {
l = m;
} else {
r = m;
}
}
return r;
}
// Возвращает true, если можно за days дней разгрузить weights с
// максимальной вместимостью maxLoad, и false в обратном случае
private boolean isValidCapacity(List<Integer> weights, int days, int maxLoad) {
int currWeight = 0;
int daysCount = 1;
for (int weight : weights) {
if (currWeight + weight <= maxLoad) {
currWeight += weight;
} else {
currWeight = weight;
daysCount++;
}
}
return daysCount <= days;
}
}
from typing import *
# Возвращает true, если можно за days дней разгрузить weights с
# максимальной вместимостью max_load, и false в обратном случае
def is_valid_capacity(weights: List[int], days: int, max_load: int) -> bool:
curr_weight = 0
days_count = 1
for weight in weights:
if curr_weight + weight <= max_load:
curr_weight += weight
else:
curr_weight = weight
days_count += 1
return days_count <= days
def find_ship_capacity(weights: List[int], days: int) -> int:
# max_weight - максимальный вес одной посылки является
# минимальной возможной вместимостью
max_weight = max(weights)
# total_weight - общая сумма весов - это максимальное
# значение ответа
total_weight = sum(weights)
# ответ будет находится в правом указателе, поэтому
# l = max_weight - 1, чтобы ответом могло быть минимальное
# допустимое значение для ответа: max_weight
l, r = max_weight - 1, total_weight
while r - l > 1:
m = (l + r) // 2
if not is_valid_capacity(weights, days, m):
l = m
else:
r = m
return r
/**
* @param {number[]} weights
* @param {number} days
* @returns {number}
*/
export function findShipCapacity(weights, days) {
// Определяет, возможна ли разгрузка с заданной вместимостью maxLoad за days дней
function isValidCapacity(weights, days, maxLoad) {
let currWeight = 0;
let daysCount = 1;
for (const weight of weights) {
if (currWeight + weight <= maxLoad) {
currWeight += weight;
} else {
currWeight = weight;
daysCount++;
}
}
return daysCount <= days;
}
// maxWeight - максимальный вес одной посылки
const maxWeight = Math.max(...weights);
// totalWeight - общая сумма всех весов
const totalWeight = weights.reduce((sum, weight) => sum + weight, 0);
// ответ будет в правом указателе, l = maxWeight - 1,
// чтобы ответ мог быть минимальным допустимым значением: maxWeight
let l = maxWeight - 1;
let r = totalWeight;
while (r - l > 1) {
const m = Math.floor((l + r) / 2);
if (!isValidCapacity(weights, days, m)) {
l = m;
} else {
r = m;
}
}
return r;
}
Оценка сложности
Время: O((sum(weights) - max(weights))*log(n)), где n - размер weights; sum(weights) - сумма всех элементов в weights; max(weights) - максимальное значение в weights