Защитный экран робота: точная мощность
Условие
На складе школьной робототехники есть робот-охранник. Перед проходом через рамку безопасности он должен включить защитный экран ровно нужной мощности, иначе рамка его не пропустит.
У робота есть k защитных пластин. Каждую пластину можно поставить не более одного раза, и тогда она добавляет к мощности экрана своё число единиц.
Нужно понять, можно ли набрать мощность ровно T. Если можно — выбрать «самый аккуратный» набор: 1) с минимальным количеством пластин; 2) если таких наборов несколько — с лексикографически минимальным списком индексов пластин (индексы считаются с 1, список сравнивается как обычно: сначала первые элементы, затем вторые и т.д.).
Формат ввода
В первой строке два целых числа k и T. Во второй строке k целых чисел a1, a2, ..., ak — мощности пластин.
Формат вывода
Если набрать ровно T нельзя, выведите одну строку NO.
Иначе выведите:
- в первой строке
YES - во второй строке число
m— сколько пластин в выбранном наборе - в третьей строке
mиндексов пластин в возрастающем порядке (еслиm = 0, третья строка должна быть пустой)
Ограничения
1 ≤ k ≤ 70 ≤ T ≤ 1000 ≤ ai ≤ 100
Пример
Ввод:
5 10
2 3 7 8 1
Вывод:
YES
2
1 4Как решать — идея подхода
Приём: Перебор подмножеств (битмаска)
Ключевое наблюдение: k ≤ 7, значит всех вариантов установки пластин всего 2^k (максимум 128). Это настолько мало, что можно честно проверить каждый набор и выбрать «самый аккуратный» по правилам.
Приём: перебор подмножеств битмаской. Число mask от 0 до 2^k - 1 кодирует, какие пластины взяли: i-я пластина взята, если mask имеет i-й бит.
План решения:
- Пройти
maskот 0 до2^k - 1. - Для текущей маски посчитать сумму
sи собрать список индексовidx(1..k) в возрастающем порядке. - Бит проверяется так:
if (mask >> i) & 1:. - Можно ускориться: если
s > T, дальше в этой маске уже нет смысла (все добавления неотрицательные) — прерываемся. - Если
s == T, сравнить набор с текущим лучшим: - сначала меньшее количество пластин
len(idx); - при равенстве — лексикографически меньший список
idx. - Если лучший набор не найден — вывести
NO, иначеYES, размер и индексы.
Сложность: O(k * 2^k), здесь это максимум 7 * 128 операций — мгновенно.
Частая ошибка: забыть про случай T = 0. Тогда подходит пустой набор (m = 0), и третья строка должна быть пустой, но её всё равно нужно вывести.
Разберись руками
Есть 5 пластин с мощностями 2, 3, 7, 8, 1. Нужно набрать ровно 10, используя каждую пластину не больше одного раза. Если вариантов несколько — берём с меньшим числом пластин, а если поровну — с более «ранними» индексами.
- Начнём с пластин 1–4 (мощности 2, 3, 7, 8). Отметь ВСЕ наборы, которые дают сумму ровно 10.
- По правилам задачи какой набор «аккуратнее» среди найденных двух: {2,3} или {1,4}?
- Теперь учитываем все 5 пластин (добавилась пластина 5 с мощностью 1). Какое минимальное количество пластин вообще нужно, чтобы набрать 10?
Идея: Перебери все возможные наборы пластин (каждую можно либо взять, либо не взять), для каждого посчитай сумму. Среди тех, где сумма ровно нужная, выбери набор с минимальным числом пластин, а если таких несколько — тот, у которого список индексов получается «раньше» при обычном сравнении слева направо.
Решить задачу с автопроверкой на Python →
Куда дальше
- Школьный этап ВсОШ по информатике — как устроен первый этап и план подготовки за четыре недели
- БВИ и льготы при поступлении — какой диплом что даёт и сколько лет он действует
- Перечневые олимпиады по информатике — олимпиады перечня Минобрнауки, их уровни и что нужно к диплому