Две команды для школьного матча
Условие
В школе собирают две команды на матч. У каждого ученика есть «сила» — целое число. Учитель хочет разделить всех на две команды так, чтобы суммы сил команд отличались как можно меньше.
Нужно найти минимально возможную разницу между суммами сил двух команд.
Формат ввода
В первой строке дано целое число n — число учеников. Во второй строке дано n целых чисел a1, a2, ..., an — силы учеников.
Формат вывода
Выведите одно целое число — минимально возможное значение |S1 - S2|, где S1 и S2 — суммы сил в двух командах.
Ограничения
2 ≤ n ≤ 201 ≤ ai ≤ 100000
Пример
Ввод:
4
10 20 15 5
Вывод:
0
Пояснение: можно разделить как (10+15) и (20+5), суммы равны 25 и 25.
Как решать — идея подхода
Приём: Перебор подмножеств (битмаски)
Ключевое наблюдение: если выбрать первую команду как подмножество с суммой S, то сумма второй — total - S. Разница тогда равна |(total - S) - S| = |total - 2*S|. Значит, задача — найти такое S (сумму какого-то подмножества), чтобы |total - 2*S| было минимальным.
Почему работает перебор: n ≤ 20, значит подмножеств всего 2^n (максимум 1 048 576) — это реально перебрать за секунды.
План решения:
- Считай
nи массив силa. - Посчитай
total = sum(a)и заведи ответbest = total. - Для каждой маски
maskот0до(1<<n)-1: - Посчитай сумму
Sэлементов, где i-й бит маски равен 1. - Вычисли текущую разницу
diff = abs(total - 2*S)и обновиbest. - Если
best == 0, можно сразу остановиться (лучше уже не будет).
Мини-сниппет формулы: diff = abs(total - 2*S)
Сложность: по времени O(n * 2^n) в лоб (для каждой маски смотрим биты), по памяти O(1).
Частая ошибка: пытаться перебрать разбиения «две команды» напрямую и считать обе суммы каждый раз. Достаточно хранить сумму только одной команды (подмножества), вторая получается как total - S, иначе легко получить лишний множитель 2 и запутаться с формулой разницы.
Разберись руками
Есть 4 ученика с силами 10, 20, 15 и 5. Мы выбираем, кто пойдёт в команду 1, а все остальные автоматически попадут в команду 2. Хотим, чтобы разница сумм сил команд была как можно меньше.
- Сначала найди общую сумму сил всех учеников: 10 + 20 + 15 + 5 = ?
- Ниже — ВСЕ варианты того, кто попал в команду 1 (команда 2 — это все остальные). Отметь индексы вариантов, где сумма сил команды 1 равна 25 (тогда команды могут выйти равными).
- Если команда 1 набрала 25, то сколько будет минимальная возможная разница между суммами сил двух команд?
Идея: Перебираем все варианты состава одной команды (это все подмножества учеников), для каждого считаем сумму этой команды и сумму второй как «всё остальное», затем сравниваем разницу сумм и запоминаем самую маленькую.
Решить задачу с автопроверкой на Python →
Куда дальше
- Школьный этап ВсОШ по информатике — как устроен первый этап и план подготовки за четыре недели
- БВИ и льготы при поступлении — какой диплом что даёт и сколько лет он действует
- Перечневые олимпиады по информатике — олимпиады перечня Минобрнауки, их уровни и что нужно к диплому