Я часто участвую в крупных вводных классах программирования (400 - 600 студентов), и когда время экзаменов приходит, нам часто приходится разделить класс на разные комнаты, чтобы убедиться, что все имеют место для экзамена.
Чтобы сделать вещи логически простыми, я обычно разбиваю класс на фамилию. Например, я мог бы отправить учеников с фамилиями A-H в одну комнату, фамилию I-L во вторую комнату, M-S в третью комнату, а T-Z - в четвертую комнату.
Задача в этом состоит в том, что комнаты часто имеют совершенно разные возможности, и может быть трудно найти способ сегментировать класс таким образом, чтобы каждый мог поместиться. Например, предположим, что распределение последних имен (для простоты) следующее:
- Фамилия начинается с A: 25
- Фамилия начинается с B: 150
- Фамилия начинается с C: 200
- Фамилия начинается с D: 50
Предположим, что у меня есть комнаты с емкостью 350, 50 и 50. Жадным алгоритмом для поиска номера может быть сортировка комнат в порядке убывания емкости, а затем попробуйте заполнить комнаты в указанном порядке. Это, к сожалению, не всегда работает. Например, в этом случае правильным вариантом является поместить фамилию A в одну комнату размером 50, фамилии B - C в комнату размером 350 и фамилию D в другую комнату размером 50. Жадный алгоритм положить фамилии А и В в комнату на 350 человек, а затем не найти места для всех остальных.
Легко решить эту проблему, просто попробовав все возможные перестановки упорядочений комнат, а затем запуская жадный алгоритм при каждом упорядочении. Это либо найдет задание, которое работает, либо сообщит, что ни один из них не существует. Тем не менее, мне интересно, есть ли более эффективный способ сделать это, учитывая, что количество комнат может быть от 10 до 20, и проверка всех перестановок может оказаться невозможной.
Подводя итог, формальная постановка задачи такова:
Вам дается гистограмма частоты последних имен учеников в классе, а также список комнат и их возможности. Ваша цель состоит в том, чтобы разделить учащихся по первой букве их фамилии, чтобы каждая комната была снабжена непрерывным блоком букв и не превышала ее.
Есть ли эффективный алгоритм для этого или, по крайней мере, тот, который эффективен для разумных размеров комнаты?
РЕДАКТИРОВАТЬ: Многие люди спрашивают о смежном состоянии. Правила:
- Каждая комната должна быть назначена не более, чем блок смежных букв, и
- Ни одно письмо не должно быть назначено двум или более комнатам.
Например, вы не могли поместить A-E, H-N и P-Z в одну комнату. Вы также не могли бы поставить A-C в одну комнату и B-D в другую.
Спасибо!