Учтите, что для N доступных комнат данная комната либо является частью выбора, либо нет, следовательно, у вас есть 2 ^ N различных вариантов выбора.Они могут быть изображены в виде древовидной схемы
x
/ \
/ \
x 1
/ \ / \
/ | | \
x 2 1 1+2
, где направление вправо означает «комната находится», а движение налево означает «комната не входит», а узлы помечены общим количеством гостей длявыбранные комнаты.Например, если вы не выбираете комнату 1 и не выбираете комнату 2, тогда общая сумма равна 0, когда вы выбираете комнату 1 и выбираете комнату 2, вы добавляете вместимость первой комнаты с вместимостью комнаты 2 (помеченнойкак 1+2
).
Хитрость в том, чтобы теперь не обходить все ветви до конца, а только до
a) сумма - это желаемое количество гостей => у вас есть решение.Не нужно углубляться в дерево.
b) сумма превышает желаемое количество гостей.Опять же, нет необходимости углубляться в дерево, так как мы только добавляем больше места.
c) вы достигли конца ветви и все еще недостаточно места.
Во всех трех случаях выможете вернуться в дерево вверх, пока не достигнете узла с нисходящим путем, который вы уже не выбрали.Продолжайте идти по этому пути и повторяйте, пока не найдете одно (или все, если хотите) решение.
Это просто основная идея.Может быть много вариантов того, как проходить по дереву, и вы можете что-то сэкономить, когда вы сортируете входной массив и используете тот факт, что несколько комнат могут вместить одинаковое количество гостей.
С другой стороны,массив из 10 элементов относительно мал.Даже с учетом комбинаторики, где факториал обычно является убийцей, 10! = 3628800
все еще находится в разумных пределах, и, возможно, достаточно простого алгоритма грубой силы.Однако 100!
- это уже совсем другая история;).