Подтема 2 из 7
Жадный выбор
Больше всего объектов — самые маленькие первыми; наибольший объект при таком количестве; обязательные объекты, покупки партиями и скидки.
Больше всего файлов
На диске свободно 60, а размеры файлов — 8, 12, 15, 19, 22 и 34. Как сохранить как можно больше файлов?
Брать файлы от самых маленьких, пока следующий помещается: так каждый выбор оставляет больше всего места остальным. Отсортируем размеры и будем добавлять файлы по одному:
Получили четыре файла. Почему пять сохранить невозможно? Потому что пять самых маленьких файлов имеют сумму 8 + 12 + 15 + 19 + 22 = 76 > 60, а любые другие пять файлов имеют не меньшую сумму. Это видно, если выписать оба набора по возрастанию друг под другом: i-й файл любого набора не меньше i-го самого маленького. На рисунке то же сравнение для наборов из четырёх файлов.
Обоснование · необязательноДоказательство для любых размеров
Пусть отсортированные размеры a₁ ≤ a₂ ≤ … ≤ aₙ. У любого выбранного набора из k файлов после его собственной сортировки b₁ ≤ b₂ ≤ … ≤ bₖ. Обязательно b₁ ≥ a₁, b₂ ≥ a₂, …, bₖ ≥ aₖ: среди всех файлов есть по крайней мере i файлов, не больших bᵢ, — это b₁, …, bᵢ, — а aᵢ — i-е наименьшее значение, поэтому bᵢ ≥ aᵢ. Следовательно, b₁ + … + bₖ ≥ a₁ + … + aₖ. То есть первые k элементов имеют минимальную возможную сумму среди всех наборов из k элементов: если не помещаются они, не поместится никакой набор из k.
Код повторяет ручные действия. Пройди его по шагам:
sizes = [19, 8, 34, 12, 22, 15]capacity = 60sizes.sort()used = 0count = 0for size in sizes: if used + size > capacity: break used += size count += 1print(count, used)Здесь used — уже занятый объём, count — количество выбранных файлов. Проверяем возможность добавления до изменения суммы.
Почему разрешён ? Потому что список отсортирован по возрастанию: если текущий файл не помещается, следующие ещё крупнее. Без сортировки такой выход из цикла мог бы пропустить маленький файл в конце списка: для [19, 8, 34, ...] цикл остановился бы на 34, не дойдя до 12 и 15.
Жадный алгоритм
Брать самое маленькое — это и есть «жадный алгоритм»? И всегда ли он прав?
Жадный алгоритм на каждом шаге делает выбор по простому правилу и больше к нему не возвращается. Прав он, только если можно объяснить, почему такой выбор не испортит итог.
Правило «из оставшихся файлов берём самый маленький» — жадное. Слово «жадный» не означает «всегда берёт самое большое»: он может выбирать самый маленький размер, самое раннее окончание, наибольшую допустимую коробку, самый дешёвый подходящий объект.
Одного ощущения «так выгоднее» мало. Объясняют двумя способами. Первый: выбранный объект оставляет не меньше возможностей. Файл поменьше оставляет больше места для следующих. Второй: можно заменить чужой выбор нашим и не ухудшить результат. Если в некотором лучшем наборе взят большой файл, а меньший не взят, их можно поменять: количество сохранится, занятое место не увеличится. Такое рассуждение называют доказательством обменом.
Важно учитывать всю формулировку. При вместимости 10 и размерах 4, 5, 6 лучший набор зависит от цели — выбери цель:
- больше всего объектов
- 4 + 5два объекта, самые маленькие
- наибольшая сумма
- 4 + 6 = 10самые маленькие дают только 9
- наибольший отдельный объект
- 6один файл помещается целиком
Максимальное количество, максимальная сумма и максимальный отдельный элемент — разные цели.
Самый большой файл
«При максимальном количестве файлов укажите наибольший файл, который может быть сохранён». Это просто последний из выбранных?
Нет. Закрепим k − 1 самых маленьких файлов и найдём наибольший файл, который влезает в оставшееся место.
Максимальное количество равно четырём, и первоначально выбраны 8, 12, 15, 19. Но наибольший файл, который может оказаться среди четырёх сохранённых, — 22: набор 8, 12, 15, 22 занимает 57 ≤ 60.
Как получить это системно? Зафиксируем три самых маленьких файла — 8, 12, 15. Они занимают 35, для четвёртого остаётся 60 − 35 = 25. Из оставшихся файлов выбираем максимальный размер, не превышающий 25. Это 22.
Почему можно зафиксировать именно k − 1 самых маленьких? Потому что они оставляют максимально возможное место для ещё одного файла. Если некоторый файл x нельзя разместить даже вместе с k − 1 самыми маленькими, то с любыми другими k − 1 файлами он тем более не поместится.
Полная программа для формата S N в первой строке:
with open("26.txt") as f: capacity, n = map(int, f.readline().split()) a = [int(f.readline()) for i in range(n)] a.sort()used = 0count = 0for size in a: if used + size > capacity: break used += size count += 1 fixed_sum = used - a[count - 1]limit = capacity - fixed_sumlargest = a[count - 1]for size in a[count - 1:]: if size > limit: break largest = size print(count, largest)Вторая половина программы — это рисунок выше: закрепили count − 1 самых маленьких и ищем наибольший файл, который помещается в оставшееся место limit.
Подробный разбор · необязательноРазбор второй половины программы
used — сумма первых count файлов, a[count - 1] — последний из них; вычитая его, получаем сумму первых count − 1 файлов. Перебор начинается с , поэтому закреплённые первые count − 1 файлов не используются повторно, а break снова держится на сортировке. Программа предполагает, что хотя бы один файл помещается; что выводить, если не помещается ни один, говорит условие.
Этот приём максимизирует один файл. Он не является способом максимизировать общую сумму выбранного набора.
Обязательные первыми
«Важные файлы перенести в первую очередь, а на оставшееся место — как можно больше остальных». Что меняется?
Обязательные объекты кладут сразу, без выбора, а жадный выбор идёт по оставшемуся месту среди остальных. Пусть файл 34 обязателен. В записи второе поле — 1 у обязательного:
capacity = 60files = [(8, 0), (12, 0), (15, 0), (19, 0), (22, 0), (34, 1)]used = sum(size for size, must in files if must)count = sum(must for size, must in files)for size in sorted(s for s, must in files if not must): if used + size > capacity: break used += size count += 1print(count, capacity - used)34 занимает своё место сразу, свободно 26: туда входят 8 и 12, а 15 уже нет. Всего три файла, свободно 6. Так же решаются задачи о грузовике, где «грузы массой от 310 до 320 кг грузят в первую очередь»: обязательность определяет условие, а не размер.
Покупка партиями
В строке файла не одно изделие, а партия: цена и количество. Как купить больше всего изделий?
Идти по партиям от дешёвых и брать из каждой сколько хватит денег: всю партию или money // price изделий.
Пусть на 500 рублей нужно купить как можно больше изделий A, а на остаток — как можно больше изделий B. Партии A: 5 штук по 20 и 10 штук по 35; партии B: 4 штуки по 25 и 30 штук по 15.
Для каждого типа идём по партиям от дешёвых к дорогим и из партии берём min(q, money // p) изделий: либо всю партию, либо сколько хватит денег. Деление нацело отвечает на вопрос «сколько раз цена помещается в остаток».
money = 500lots = {"A": [(20, 5), (35, 10)], "B": [(25, 4), (15, 30)]}bought = {}for kind in "AB": count = 0 for price, q in sorted(lots[kind]): take = min(q, money // price) count += take money -= take * price if take < q: break bought[kind] = countprint(bought["A"], bought["B"], money)Все изделия A стоят 5 · 20 + 10 · 35 = 450, на остаток 50 покупаем 3 изделия B по 15 и остаётся 5. Почему после неполной партии можно остановиться? Денег не хватило даже на изделие этой партии, а следующие партии не дешевле.
Покупки двух типов
Купить больше всего изделий, а среди таких покупок — больше изделий типа A. Как учесть второй критерий?
Количество находим как раньше — самыми дешёвыми. Потом перебираем, сколько из них будет изделий A: для каждого числа самая дешёвая покупка однозначна.
В подборке есть задачи с тремя приоритетами: купить максимальное общее количество изделий, затем максимальное количество изделий типа A, затем потратить минимальную сумму. Возьмём бюджет 36, цены изделий A — 4, 9, 14, изделий B — 3, 5, 6, 10.
Сначала определим максимальное общее количество. Все цены по возрастанию: 3, 4, 5, 6, 9, 10, 14. Пять самых дешёвых стоят 27, шесть — уже 37 > 36. Значит, нужно купить ровно пять изделий — это рассуждение прошлого шага.
Теперь спрашиваем: сколько из этих пяти может быть изделий A? Если берём x изделий A, изделий B должно быть 5 − x. Для фиксированного x самая дешёвая покупка состоит из x самых дешёвых A и 5 − x самых дешёвых B.
Значит, достаточно быстро находить суммы первых нескольких элементов. Для этого строят накопленные суммы, их также называют префиксными суммами: «префикс» — начальный участок последовательности. Для A = 4, 9, 14 получим PA = 0, 4, 13, 27: PA[0] — стоимость нуля изделий, PA[1] — одного самого дешёвого, PA[2] — двух, PA[3] — трёх. Каждая следующая накопленная сумма равна предыдущей плюс очередная цена. Для B: PB = 0, 3, 8, 14, 24.
| Количество A | Количество B | Минимальная стоимость | Подходит? |
|---|---|---|---|
| 1 | 4 | 4 + 24 = 28 | Да |
| 2 | 3 | 13 + 14 = 27 | Да |
| 3 | 2 | 27 + 8 = 35 | Да |
Выбираем три A и два B. Остаток равен 1.
budget = 36a = sorted([4, 9, 14])b = sorted([3, 5, 6, 10])count = spent = 0for price in sorted(a + b): if spent + price > budget: break spent += price count += 1 prefix_a = [0]for price in a: prefix_a.append(prefix_a[-1] + price)prefix_b = [0]for price in b: prefix_b.append(prefix_b[-1] + price) best_a = best_cost = 0for count_a in range(count + 1): count_b = count - count_a if count_a > len(a) or count_b > len(b): continue cost = prefix_a[count_a] + prefix_b[count_b] if cost <= budget: best_a = count_a best_cost = costprint(best_a, budget - best_cost)Здесь нет перебора всех наборов покупок: перебирается только количество изделий A, а лучший набор с таким количеством строится однозначно.
Обоснование · необязательноПочему программа выполняет все три условия
Первое — количество: count найден набором самых дешёвых, как в прошлом шаге. Второе — больше A: count_a перебирается по возрастанию, поэтому ответ можно просто перезаписывать — каждый следующий подходящий вариант содержит больше A. Третье — дешевле: для каждого состава мы уже берём самые дешёвые изделия обоих типов. пропускает составы, для которых изделий одного из типов не хватает.
Скидки
«Каждый третий товар бесплатно»: какой именно товар окажется бесплатным?
Сначала понять, кто расставляет товары и кому выгодна расстановка: покупатель делает бесплатными самые дорогие возможные товары, продавец — самые дешёвые.
Одна фраза об акции ещё не определяет алгоритм. Выбери правило:
- можно выбрать любые k товаров со скидкой
- выгодно выбирать наиболее дорогие подходящие
- в каждой паре скидка на дешёвый товар
- нужно выгодно составить пары
- в каждой тройке бесплатно самый дешёвый
- нужно выгодно составить тройки
- продавец сам переставляет товары
- нужно учитывать цель продавца
- скидка действует только выше порога
- сначала выделяются подходящие товары
Рассмотрим конкретное правило:
Все товары нужно купить. Их можно разбить на тройки. В каждой полной тройке самый дешёвый товар бесплатный.
Цены: 100, 90, 80, 70, 60, 50, 40. Выгодные тройки — 100, 90, 80 и 70, 60, 50: бесплатно получаем 80 и 50, а 40 покупаем отдельно. Сумма всех цен 490, стоимость покупки 490 − 80 − 50 = 360. После сортировки по убыванию бесплатны элементы с индексами 2, 5, 8, …; третий параметр — шаг:
prices = [70, 100, 40, 90, 50, 80, 60]prices.sort(reverse=True)free_sum = 0for i in range(2, len(prices), 3): free_sum += prices[i]print(sum(prices) - free_sum)Соседние тройки отсортированного списка дают наибольшую скидку: каждый бесплатный товар получается настолько дорогим, насколько это вообще возможно.
Обоснование · необязательноПочему соседние тройки оптимальны
Чтобы получить один бесплатный товар некоторой цены, к нему нужны ещё два товара не дешевле. Значит, самый дорогой бесплатный товар не может быть дороже третьего по цене, второй по дороговизне бесплатный — не дороже шестого, третий — не дороже девятого. Разбиение отсортированного списка на соседние тройки достигает этих границ.
Правило может работать и в пользу покупателя: если в каждой тройке бесплатен самый дорогой товар, к каждому бесплатному нужны два более дешёвых спутника. Тогда бесплатными выгодно сделать ⌊n / 3⌋ самых дорогих товаров, а спутников взять из дешёвых: для тех же цен бесплатны 100 и 90.
В подборках встречается и «каждый четвёртый товар в чеке за полцены». Покупатель ставит на 4-е, 8-е, … места самые дорогие товары, а касса, которая сортирует цены себе в пользу, — самые дешёвые. Для цен 100, 90, 80, 70, 60, 50, 40, 30 за полцены идут два товара: у покупателя 100 и 90 — он платит 425, у кассы 30 и 40 — 485.
prices = [60, 100, 30, 80, 50, 90, 40, 70]prices.sort(reverse=True)q = len(prices) // 4buyer = sum(prices) - sum(prices[:q]) // 2shop = sum(prices) - sum(prices[-q:]) // 2print(buyer, shop)Если товары переставляет продавец и хочет дать скидку поменьше, скидка достаётся самым дешёвым из подходящих товаров: продавец ставит их на чётные места. Например, «скидка 25 % на каждый второй товар дороже 50 рублей»: из k таких товаров скидку получат ⌊k / 2⌋ самых дешёвых.
Скидка в процентах и округление вверх
Пусть скидка 25 % применяется к товарам с суммарной исходной ценой D, а сумма всех цен — T. Тогда точная итоговая стоимость T − D/4 = (4T − D)/4. Если всю итоговую сумму нужно округлить вверх, делают целочисленно: (x + d - 1) // d — это x/d, округлённое вверх, для неотрицательного целого x.
prices = [65, 300, 45, 120, 200, 80]big = sorted(p for p in prices if p > 50)discount = big[:len(big) // 2]total = sum(prices)numerator = 4 * total - sum(discount)print(discount, (numerator + 3) // 4)Товаров дороже 50 пять, скидку получают два самых дешёвых из них — 65 и 80. Точная стоимость 810 − 145/4 = 773,75, после округления вверх — 774. Нельзя округлять стоимость каждого товара отдельно, если условие требует округлить только общую сумму.
Итого
- Больше всегоот самых маленьких, break после первого лишнего
- Наибольший при kзакрепить k − 1 самых маленьких
- Жадный выборобъяснить: оставляет не меньше возможностей
- Обязательныесначала они, потом выбор по остатку
- Партии
min(q, money // price) - Скидкипокупатель — дорогие, продавец — дешёвые
Проверьте себя
Ответь сначала сам, потом открой ответ.
break без сортировки и какой ответ верный?ОтветСкрыть ответ
ОтветСкрыть ответ
ОтветСкрыть ответ
ОтветСкрыть ответ
ОтветСкрыть ответ
Практика
Для проверки ответов нужен JavaScript. Условия, подсказки и решения доступны ниже.
Вместимость 30
Вместимость 30, размеры 5, 7, 8, 9, 12, 16. Найди максимальное количество файлов и максимальный возможный размер одного файла при таком количестве.
Введите два числа через пробел в том порядке, в каком их спрашивают.
Подсказка
Набери самые маленькие, затем замени последний на наибольший помещающийся.
Решение
4 9: четыре самых маленьких занимают 29; после фиксации 5, 7, 8 остаётся 10, из 9, 12, 16 помещается 9.
Решение программой
a = sorted([5, 7, 8, 9, 12, 16])capacity = 30used = count = 0for x in a: if used + x > capacity: break used += x count += 1limit = capacity - (used - a[count - 1])largest = max(x for x in a[count - 1:] if x <= limit)print(count, largest)Ответ: 4 9
Вместимость 10
Вместимость 10, размеры 4, 5, 6. Найди максимальное количество файлов, максимальную сумму сохранённых файлов и наибольший файл среди наборов максимального количества.
Введите три числа через пробел в том порядке, в каком их спрашивают.
Подсказка
Переберите все наборы из максимального количества файлов.
Решение
2 файла, сумма 10 (4 + 6), наибольший файл 6: набор 4 + 6 тоже из двух файлов.
Решение программой
from itertools import combinations a = [4, 5, 6]capacity = 10k = max(r for r in range(len(a) + 1) if sum(sorted(a)[:r]) <= capacity)sets = [c for c in combinations(a, k) if sum(c) <= capacity]print(k, max(map(sum, sets)), max(map(max, sets)))Ответ: 2 10 6
Архив на диске
В файле 26-3.txt в первой строке записаны свободный объём диска S и количество файлов N, в каждой следующей — размер одного файла (натуральное число, не больше 100). Определи максимальное количество файлов, которые можно сохранить на диске, и максимальный размер файла, который может быть сохранён при условии, что сохранено максимальное количество файлов.
Введите два числа через пробел в том порядке, в каком их спрашивают.
Подсказка
Закрепите все файлы, кроме последнего, и найди наибольший, который поместится вместо него.
Решение
2694 93: после фиксации 2693 самых маленьких файлов места хватает на файл 93 — он больше, чем 2694-й по возрастанию.
Решение программой
with open('26-3.txt') as f: capacity, n = map(int, f.readline().split()) a = sorted(int(line) for line in f) used = count = 0for x in a: if used + x > capacity: break used += x count += 1limit = capacity - (used - a[count - 1])largest = max(x for x in a[count - 1:] if x <= limit)print(count, largest)Ответ: 2694 93
Обязательные файлы первыми
На диске свободно 100. Файлы (размер, обязательный ли): (30, да), (18, нет), (7, нет), (25, да), (12, нет), (40, нет), (9, нет), (22, нет). Обязательные файлы переносят в первую очередь, а на оставшееся место — как можно больше остальных. Сколько файлов перенесут и сколько места останется?
Введите два числа через пробел в том порядке, в каком их спрашивают.
Подсказка
Сначала положи обязательные, затем остальные от самых маленьких, пока помещаются.
Решение
Обязательные занимают 55. Дальше 7, 9 и 12 — 83; 18 уже не помещается. Файлов 5, свободно 17.
Решение программой
capacity = 100files = [(30, 1), (18, 0), (7, 0), (25, 1), (12, 0), (40, 0), (9, 0), (22, 0)]used = sum(size for size, must in files if must)count = sum(must for size, must in files)for size in sorted(s for s, must in files if not must): if used + size > capacity: break used += size count += 1print(count, capacity - used)Ответ: 5 17
Партии A, затем B
Есть 300 рублей. Партии изделий A: 4 штуки по 25 и 3 штуки по 40; партии изделий B: 6 штук по 10 и 5 штук по 30. Сначала покупают как можно больше A, на остаток — как можно больше B. Сколько куплено изделий B и сколько денег осталось?
Введите два числа через пробел в том порядке, в каком их спрашивают.
Подсказка
Внутри каждого типа партии берут от дешёвых, из партии — сколько хватает денег.
Решение
6 20: A стоят 100 + 120, на остаток 80 — шесть изделий по 10, осталось 20.
Решение программой
money = 300a = [(4, 25), (3, 40)]b = [(6, 10), (5, 30)]for batches in (a, b): bought = 0 for count, price in sorted(batches, key=lambda p: p[1]): take = min(count, money // price) bought += take money -= take * priceprint(bought, money)Ответ: 6 20
Больше всего, затем больше A
Бюджет 20, цены изделий A — 3, 8, 9, изделий B — 2, 4, 7. Нужно купить как можно больше изделий, среди таких способов — как можно больше A, среди них — самый дешёвый. Сколько изделий A купят и сколько денег останется?
Введите два числа через пробел в том порядке, в каком их спрашивают.
Подсказка
Количество находят по самым дешёвым; затем перебирают число изделий A.
Решение
2 3: можно купить четыре изделия (2 + 3 + 4 + 7 = 16); три A стоят 20 и не помещаются с B, два A и два B — 11 + 6 = 17.
Решение программой
a = sorted([3, 8, 9])b = sorted([2, 4, 7])money = 20total = 0count = 0for p in sorted(a + b): if total + p > money: break total += p count += 1best = Nonefor ca in range(count + 1): cb = count - ca if ca <= len(a) and cb <= len(b): spent = sum(a[:ca]) + sum(b[:cb]) if spent <= money: best = (ca, money - spent)print(*best)Ответ: 2 3
Изделия A и B
В файле 26-4.txt в первой строке записаны количество изделий у поставщика N и выделенная сумма M, в каждой следующей — цена изделия и его тип (латинская буква A или B). Нужно купить как можно больше изделий; если это можно сделать разными способами — купить как можно больше изделий A; если и так способов несколько — потратить как можно меньше. Запиши количество купленных изделий A, затем оставшуюся сумму.
Введите два числа через пробел в том порядке, в каком их спрашивают.
Подсказка
Количество — по самым дешёвым; затем перебор числа A с накопленными суммами.
Решение
163 85: перебор числа изделий A с накопленными суммами; если просто купить самые дешёвые изделия, изделий A было бы меньше.
Решение программой
with open('26-4.txt') as f: n, money = map(int, f.readline().split()) items = [line.split() for line in f] a = sorted(int(p) for p, t in items if t == 'A')b = sorted(int(p) for p, t in items if t == 'B')spent = count = 0for p in sorted(a + b): if spent + p > money: break spent += p count += 1pa, pb = [0], [0]for p in a: pa.append(pa[-1] + p)for p in b: pb.append(pb[-1] + p)best = Nonefor ca in range(count + 1): cb = count - ca if ca < len(pa) and cb < len(pb): if pa[ca] + pb[cb] <= money: best = (ca, money - pa[ca] - pb[cb])print(*best)Ответ: 163 85
Каждый четвёртый за полцены
В магазине акция: каждый четвёртый товар в чеке — за полцены. Цены товаров: 120, 46, 300, 80, 16, 60, 210, 96, 40, 180, 70, 24. Покупатель раскладывает товары на ленте так, чтобы заплатить как можно меньше, а касса сортирует их так, чтобы стоимость была как можно больше. Сколько заплатил бы покупатель при своей раскладке и сколько возьмёт касса?
Введите два числа через пробел в том порядке, в каком их спрашивают.
Подсказка
За полцены идут len // 4 товаров: покупателю выгодны самые дорогие, кассе — самые дешёвые.
Решение
За полцены идут три товара. Покупатель ставит на 4-е, 8-е и 12-е места 300, 210 и 180: 1242 − 345 = 897. Касса ставит туда 16, 24 и 40: 1242 − 40 = 1202.
Решение программой
prices = [120, 46, 300, 80, 16, 60, 210, 96, 40, 180, 70, 24]prices.sort(reverse=True)q = len(prices) // 4total = sum(prices)buyer = total - sum(prices[:q]) // 2shop = total - sum(prices[-q:]) // 2print(buyer, shop)Ответ: 897 1202
Тройки с бесплатным товаром
Цены 120, 45, 300, 80, 60, 95, 210, 150. Товары делят на тройки, в каждой полной тройке один товар бесплатный. Сколько заплатит покупатель, если бесплатен самый дешёвый в тройке и тройки он составляет сам? А если бесплатен самый дорогой?
Введите два числа через пробел в том порядке, в каком их спрашивают.
Подсказка
По убыванию цен: бесплатный самый дешёвый — каждый третий; самый дорогой — первые n // 3.
Решение
830 и 550: в первом случае бесплатны 150 и 80, во втором — 300 и 210.
Решение программой
p = sorted([120, 45, 300, 80, 60, 95, 210, 150], reverse=True)print(sum(p) - sum(p[2::3]), sum(p) - sum(p[:len(p) // 3]))Ответ: 830 550
Каждый второй дороже 100
Те же цены. Скидка 20 % — на каждый второй товар дороже 100 рублей; порядок товаров выбирает продавец так, чтобы скидка была наименьшей; итог округляется вверх до рубля. Найди итог и цену самого дорогого товара со скидкой.
Введите два числа через пробел в том порядке, в каком их спрашивают.
Подсказка
Скидку получают самые дешёвые из дорогих товаров — их половина.
Решение
1006 150: дороже 100 четыре товара, скидка на 120 и 150; 1060 − 270 + 216 = 1006.
Решение программой
prices = [120, 45, 300, 80, 60, 95, 210, 150]big = sorted(p for p in prices if p > 100)disc = big[:len(big) // 2]rest = sum(prices) - sum(disc)print(rest + (4 * sum(disc) + 4) // 5, max(disc))Ответ: 1006 150
Самый дешёвый в тройке бесплатно
В файле 26-5.txt в первой строке записано количество товаров N, в каждой следующей — цена товара. В магазине акция: товары делят на тройки, и в каждой полной тройке самый дешёвый товар бесплатный; оставшиеся один-два товара оплачиваются полностью. Покупатель покупает все товары и делит их на тройки самым выгодным для себя способом. Запиши сумму, которую он заплатит, затем цену самого дорогого бесплатного товара.
Введите два числа через пробел в том порядке, в каком их спрашивают.
Подсказка
По убыванию цен бесплатен каждый третий товар.
Решение
5142686 4997: бесплатны элементы с индексами 2, 5, 8, … после сортировки по убыванию.
Решение программой
with open('26-5.txt') as f: f.readline() a = [int(line) for line in f] a.sort(reverse=True)free = a[2::3]print(sum(a) - sum(free), free[0])Ответ: 5142686 4997