Байдарки для команды
Условие
После тренировки по гребле команда хочет переправиться на другой берег на учебных байдарках.
Каждая байдарка выдерживает суммарный вес не больше L и в ней могут сидеть не более двух спортсменов. Тренер хочет выдать байдарки так, чтобы байдарок было как можно меньше.
Важно: числа большие (как на олимпиадах), используйте 64-битные целые. В Python это не проблема.
Формат ввода
В первой строке даны два целых числа n и L — число спортсменов и грузоподъёмность байдарки. Во второй строке даны n целых чисел w1, w2, ..., wn — веса спортсменов.
Формат вывода
Выведите одно целое число — минимальное количество байдарок.
Ограничения
- 2 ≤ n ≤ 35000
- 1 ≤ L ≤ 2·10^9
- 1 ≤ wi ≤ 10^9
- Гарантируется, что wi ≤ L для всех i (то есть каждого спортсмена можно посадить хотя бы одного).
Пример
Ввод:
4 10
6 6 4 4
Вывод:
2Как решать — идея подхода
Приём: Жадный алгоритм + два указателя после сортировки
Ключевое наблюдение: если в байдарке можно максимум 2 человека, то «самый тяжёлый» спортсмен задаёт почти всё. Ему выгоднее всего искать самого лёгкого напарника: если даже с самым лёгким он не помещается, значит он точно поедет один.
Это и есть жадный выбор: берём самого тяжёлого из оставшихся и пробуем добавить к нему самого лёгкого. Такой шаг не ухудшает ответ, потому что тяжёлого всё равно нужно куда-то посадить, а посадить к нему кого-то тяжелее, чем самый лёгкий, только сложнее.
План решения:
- Считай n, L и массив весов.
- Отсортируй веса по возрастанию.
- Поставь два указателя: i = 0 (самый лёгкий), j = n-1 (самый тяжёлый), ответ boats = 0.
- Пока i <= j:
- Увеличь boats на 1 (мы выделяем одну байдарку под спортсмена j).
- Если i == j — это последний человек, остановись.
- Если
w[i] + w[j] <= L, то они едут вместе: сделай i += 1 и j -= 1. - Иначе тяжёлый едет один: сделай только j -= 1.
Мини-сниппет условия шага: if w[i] + w[j] <= L: i += 1; j -= 1 else: j -= 1
Сложность: сортировка O(n log n), проход двумя указателями O(n).
Частая ошибка: двигать i, когда пара не помещается (нельзя «облегчить» тяжёлого, меняя лёгкого на более тяжёлого). Также не забудь корректно обработать случай i == j.
Разберись руками
Есть 4 спортсмена с весами 6, 6, 4, 4. В одну байдарку можно посадить максимум двоих, и их суммарный вес должен быть не больше 10. Нужно понять, как рассаживать, чтобы байдарок было как можно меньше.
- Первый ход — удобно отсортировать веса по возрастанию. Какой список получится из 6 6 4 4?
- Попробуем самый «выгодный сейчас» вариант: посадить самого тяжёлого (6) вместе с самым лёгким (4). Сколько будет 6 + 4?
- Прогоним рассадку до конца на нашем примере. Записывай, какие веса ОСТАЛИСЬ после каждого шага (в порядке возрастания, через запятую).
- Сколько байдарок получилось по этому прогону?
Идея: Удобно сначала упорядочить веса. Дальше каждый раз смотри на самого тяжёлого: пытайся посадить его с самым лёгким, если вместе помещаются; если нет — тяжёлый едет один. Так шаг за шагом считаешь, сколько байдарок нужно.
Решить задачу с автопроверкой на Python →
Куда дальше
- Школьный этап ВсОШ по информатике — как устроен первый этап и план подготовки за четыре недели
- Перечневые олимпиады: что это и что дают — весь перечень Минобрнауки: уровни, срок диплома, разрезы по предметам и классам
- Олимпиада по информатике: с чего начать — два мира олимпиад — ВсОШ и перечневые: этапы, задания и на каком языке писать