То, что вы ищете, это Динамическое программирование .
На самом деле вам не нужно перечислять все возможные комбинации для всех возможных значений, потому что вы можете построить его поверх предыдущих ответов.
Ваш алгоритм должен принимать 2 параметра:
- Список возможных значений монет, здесь
[1, 5, 10, 25]
- Диапазон охвата, здесь
[1, 99]
И цель состоит в том, чтобы вычислить минимальный набор монет, необходимый для этого диапазона.
Самый простой способ - действовать снизу вверх:
Range Number of coins (in the minimal set)
1 5 10 25
[1,1] 1
[1,2] 2
[1,3] 3
[1,4] 4
[1,5] 5
[1,5]* 4 1 * two solutions here
[1,6] 4 1
[1,9] 4 1
[1,10] 5 1 * experience tells us it's not the most viable one :p
[1,10] 4 2 * not so viable either
[1,10] 4 1 1
[1,11] 4 1 1
[1,19] 4 1 1
[1,20] 5 1 1 * not viable (in the long run)
[1,20] 4 2 1 * not viable (in the long run)
[1,20] 4 1 2
Это довольно просто, на каждом шаге мы можем продолжить, добавив не более одной монеты, нам просто нужно знать, где. Это сводится к тому, что диапазон [x,y]
включен в [x,y+1]
, поэтому минимальный набор для [x,y+1]
должен включать минимальный набор для [x,y]
.
Как вы, возможно, заметили, иногда бывают нерешительные ситуации, то есть несколько наборов имеют одинаковое количество монет. В этом случае можно только позднее решить, какой из них следует отбросить.
Должна быть возможность улучшить время ее выполнения, если заметить, что добавление монеты обычно позволяет вам охватить гораздо больший диапазон, чем тот, для которого вы ее добавили, я думаю.
Например, обратите внимание, что:
[1,5] 4*1 1*5
[1,9] 4*1 1*5
мы добавляем никель для покрытия [1,5]
, но это дает нам до [1,9]
бесплатно!
Тем не менее, когда я имею дело с возмутительными наборами ввода [2,3,5,10,25]
для покрытия [2,99]
, я не уверен, как быстро проверить диапазон, охватываемый новым набором, иначе это будет более эффективно.