Ответ можно найти с помощью простой рекурсии, которую я продемонстрирую на примере из вопроса.
На первом уровне рекурсии решаемая проблема:
target=4 count=6 allowed={4,3,2,2,1,1} chosen={}
Первый уровень выбирает каждое уникальное значение в цикле, а затем выполняет рекурсивный вызов.Таким образом, рекурсивные вызовы с первого уровня:
target=0 size=5 allowed={3,2,2,1,1} chosen={4}
target=1 size=4 allowed={2,2,1,1} chosen={3}
target=2 size=3 allowed={2,1,1} chosen={2}
target=3 size=1 allowed={1} chosen={1}
Ключевым моментом здесь является то, что массив разрешенных значений становится меньше на каждом уровне рекурсии.Можно использовать только те значения, которые следуют за выбранным значением.Так, например, когда первый уровень рекурсии выбирает значение 3, тогда разрешены только значения меньше 3.В случае дубликатов выбирается первый дубликат, и допустимые значения ограничиваются оставшимися дубликатами и любыми меньшими значениями.
На втором уровне рекурсии, когда параметры
target=0 size=5 allowed={3,2,2,1,1} chosen={4}
Это успешный базовый случай: target
равен 0. В этом случае добавляет {4} в список вывода , поскольку это решение.
На втором уровне рекурсии, когда параметры
target=1 size=4 allowed={2,2,1,1} chosen={3}
Код должен пропускать 2, так как 2 больше, чем цель.Таким образом, единственный рекурсивный вызов -
target=0 size=1 allowed={1} chosen={3,1}
Это опять-таки базовый случай, поэтому третий уровень рекурсии добавит {3,1} к выводу .
На втором уровне рекурсии, когда параметры
target=2 size=3 allowed={2,1,1} chosen={2}
, будет два рекурсивных вызова
target=0 size=2 allowed={1,1} chosen={2,2}
target=1 size=1 allowed={1} chosen={2,1}
Первый из них - базовый случай, поэтому добавить {2,2} к выводу .Другой рекурсивный вызов в конечном итоге добавит {2,1,1} к выводу .
На втором уровне рекурсии, когда параметры
target=3 size=1 allowed={1} chosen={1}
есть один рекурсивный вызов
target=2 size=0 allowed={} chosen={1,1}
Это базовый случай сбоя: target
не равен нулю, а size
равен 0.
Обратите внимание, что когдапроблема решается таким образом, генерируются только уникальные решения, поэтому нет необходимости удалять дубликаты решений.
Также обратите внимание, что максимальная глубина рекурсии определяется S
, поэтому важно, чтобы S
былоограничено относительно небольшим числом (S <= 12
квалифицируется как достаточно маленькое).