Ответ
Числа Фибоначчи — это последовательность целых чисел, где каждое последующее число равно сумме двух предыдущих. Стандартная последовательность начинается с 0 и 1: 0, 1, 1, 2, 3, 5, 8, 13, 21, ...
Наивная рекурсивная реализация на C++ (неэффективная):
int fibonacci(int n) {
if (n <= 1) return n;
return fibonacci(n - 1) + fibonacci(n - 2);
}
Эта реализация имеет экспоненциальную временную сложность O(2ⁿ) из-за повторяющихся вычислений.
Оптимальная итеративная реализация с динамическим программированием (O(n)):
int fibonacci(int n) {
if (n <= 1) return n;
int a = 0, b = 1, c;
for (int i = 2; i <= n; ++i) {
c = a + b;
a = b;
b = c;
}
return b;
}
Применение в C++:
- Тестирование рекурсии и оптимизации хвостовых вызовов.
- Бенчмаркинг алгоритмов.
- Реализация алгоритмов, использующих золотое сечение (например, в хешировании).
Ответ 18+ 🔞
А, числа Фибоначчи! Ну классика ж, ёпта. Каждый второкурсник на них мозги свои первые прокачивает, а потом охуевает от того, как же он раньше тупил.
Смотри, суть-то проще пареной репы. Берёшь два числа, складываешь — получаешь третье. Потом второе и третье складываешь — получаешь четвёртое. И так до бесконечности, пока руки не отвалятся. Начинается всё с 0 и 1. Дальше идёт 1 (0+1), потом 2 (1+1), 3 (1+2), 5 (2+3)... Ну ты понял, пизда рулю.
Вот только если делать это в лоб, через рекурсию, как многие первым делом лепят, то будет тебе хиросима и нигерсраки, а не вычисление. Смотри, какой код обычно пишут:
int fibonacci(int n) {
if (n <= 1) return n;
return fibonacci(n - 1) + fibonacci(n - 2);
}
Выглядит-то вроде изящно, да? А на деле — манда с ушами полнейшая. Эта штука будет считать одно и то же овердохуища раз. Чтобы посчитать fibonacci(5), она полезет в fibonacci(4) и fibonacci(3). А чтобы посчитать fibonacci(4), ей опять понадобится fibonacci(3). И так она будет вздрачивать одни и те же значения до посинения, пока стек не взвоет от боли. Сложность — O(2ⁿ), то есть для n=50 комп начнёт бздеть и накроется медным тазом. Доверия ебать ноль к такому подходу.
Теперь смотри, как умные люди делают. Берут два стакана, простите, переменные, и просто идут по порядку. Э бошка думай!
int fibonacci(int n) {
if (n <= 1) return n;
int a = 0, b = 1, c;
for (int i = 2; i <= n; ++i) {
c = a + b;
a = b;
b = c;
}
return b;
}
Вот это уже дело! Сложность O(n), то есть для n=1000 он моргнёт и выдаст ответ, а не будет ебись оно конём до следующего ледникового периода. Это и есть динамическое программирование в его простейшем и красивейшем виде — просто запоминаем предыдущие результаты, а не вычисляем их миллион раз. Удивление пиздец, как же это просто и эффективно.
А где это, спрашивается, применяется? Да хуй с горы, применений овердохуища.
- Тестирование рекурсии. Преподы обожают на этом студентов ловить, чтобы те сам от себя охуели, когда их "изящный" рекурсивный код для 45-го числа считает полчаса.
- Бенчмаркинг. Отличный способ понять, насколько компилятор умеет оптимизировать хвостовую рекурсию или насколько быстр твой новый комп. Запустил несколько алгоритмов — и сразу видно, где распиздяй написал, а где код летает.
- Золотое сечение. Эти числа к нему приближаются. А золотое сечение — это уже и хеширование, и графика, и архитектура, да ебушки-воробушки, куча всего. Красота, одним словом.
Так что запомни: если видишь наивную рекурсию Фибоначчи в проде — беги. Беги быстрее, ибо рядом пидарас шерстяной, который ходит по охуенно тонкому льду над пропастью тормозов и падений системы.