Я не буду писать код для вас (так как это отличное упражнение), но это классическая проблема динамического программирования.Вы на правильном пути с повторением;Это правда, что
S (0) = 1
Так как, если вы находитесь у подножия лестницы, есть только один способ сделать это.У нас также есть это
S (1) = 1
Потому что, если вы на один шаг выше, ваш единственный вариант - сделать один шаг вниз, и в этот момент вы находитесь наbottom.
Отсюда легко найти повторяемость числа решений.Если вы думаете об этом, любая последовательность шагов, которую вы делаете, заканчивается либо одним маленьким шагом в качестве последнего шага, либо одним большим шагом в качестве последнего шага.В первом случае каждое из S (n - 1) решений для n - 1 ступеней можно расширить в решение, сделав еще один шаг, а во втором случае каждое из S (n - 2) решений для n- 2 лестницы можно расширить в решение, сделав два шага.Это дает повторение
S(n) = S(n - 2) + S(n - 1)
Обратите внимание, что для оценки S (n) вам нужен только доступ к S (n - 2) и S (n - 1).Это означает, что вы могли бы решить эту проблему с помощью динамического программирования, используя следующую логику:
- Создать массив
S
с n + 1 элементом в нем, проиндексированный на 0, 1, 2, ...,n. - Set
S[0] = S[1] = 1
- Для i от 2 до n включительно, установить
S[i] = S[i - 1] + S[i - 2]
. - Return
S[n]
.
Среда выполнения для этого алгоритма - прекрасное O (n) с использованием O (n) памяти.
Однако, возможно сделать намного лучше, чем это.В частности, давайте взглянем на первые несколько членов последовательности, которые
S(0) = 1
S(1) = 1
S(2) = 2
S(3) = 3
S(4) = 5
Это очень похоже на последовательность Фибоначчи, и на самом деле вы можете увидеть, что
S(0) = F(1)
S(1) = F(2)
S(2) = F(3)
S(3) = F(4)
S(4) = F(5)
Это говорит о том, что в общем случае S (n) = F (n + 1).Фактически мы можем доказать это с помощью индукции на n
следующим образом.
В качестве базовых случаев мы имеем, что
S(0) = 1 = F(1) = F(0 + 1)
и
S(1) = 1 = F(2) = F(1 + 1)
Для индуктивногошаг, мы получаем это
S(n) = S(n - 2) + S(n - 1) = F(n - 1) + F(n) = F(n + 1)
И вуаля!Мы получили эту серию, написанную с точки зрения чисел Фибоначчи.Это здорово, потому что можно вычислить числа Фибоначчи в O (1) пространстве и O (LG N) времени.Есть много способов сделать это.Используется тот факт, что
F (n) = (1 / √ (5)) (Φ n + φ n )
Здесь, Φ - золотое сечение, (1 + √5) / 2 (около 1,6), а φ - 1 - Φ, около -0,6.Поскольку этот второй член очень быстро падает до нуля, вы можете получить n-е число Фибоначчи, вычислив
(1 / √ (5)) Φ n
И округливвниз.Кроме того, вы можете вычислить Φ n за O (lg n) за счет повторного возведения в квадрат.Идея состоит в том, что мы можем использовать это крутое повторение:
x 0 = 1
x 2n = x n * x n
x 2n + 1 = x * x n * x n
Вы можете показать с помощью быстрого индуктивного аргумента, что это заканчивается O (LG N) времени, что означает, что вы можете решить эту проблему, используя O (1) пространство и O (LG N) время, которое существенно лучше, чем решение DP.
Надеюсь, это поможет!