Да, ваше понимание правильное.
Это называется динамическое программирование . Обычно это общий компромисс между временем выполнения памяти.
В случае с fibo вам даже не нужно все кэшировать:
[править]
Автор вопроса, похоже, ищет общий метод кеширования, а не метод вычисления Фибоначчи. Ищите википедию или посмотрите код другого автора, чтобы получить этот ответ. Эти ответы линейны по времени и памяти.
** Вот алгоритм линейного времени O (n), постоянный в памяти **
in OCaml:
let rec fibo n =
let rec aux = fun
| 0 -> (1,1)
| n -> let (cur, prec) = aux (n-1) in (cur+prec, cur)
let (cur,prec) = aux n in prec;;
in C++:
int fibo(int n) {
if (n == 0 ) return 1;
if (n == 1 ) return 1;
int p = fibo(0);
int c = fibo(1);
int buff = 0;
for (int i=1; i < n; ++i) {
buff = c;
c = p+c;
p = buff;
};
return c;
};
Это выполняется в линейное время. Но лог реально возможен !!!
Программа Ру также линейна, но намного медленнее и использует память.
Вот алгоритм журнала O (log (n))
Теперь для алгоритма времени журнала (намного быстрее), вот метод:
Если вы знаете, что u (n), u (n-1), вычисление u (n + 1), u (n) можно выполнить, применив матрицу:
| u(n+1) | = | 1 1 | | u(n) |
| u(n) | | 1 0 | | u(n-1) |
Так что у вас есть:
| u(n) | = | 1 1 |^(n-1) | u(1) | = | 1 1 |^(n-1) | 1 |
| u(n-1) | | 1 0 | | u(0) | | 1 0 | | 1 |
Вычисление экспоненты матрицы имеет логарифмическую сложность.
Просто рекурсивно реализуй идею:
M^(0) = Id
M^(2p+1) = (M^2p) * M
M^(2p) = (M^p) * (M^p) // of course don't compute M^p twice here.
Вы также можете просто диагонализировать его (не сложно), вы найдете золотое число и его сопряжение в его собственном значении, и в результате вы получите ТОЧНУЮ математическую формулу для u (n). Он содержит степени этих собственных значений, так что сложность все равно будет логарифмической.
Фибо часто берется в качестве примера для иллюстрации динамического программирования, но, как вы видите, это не совсем уместно.
@ Джон:
Я не думаю, что это имеет какое-либо отношение к хешу.
@ John2:
Карта немного общая, не правда ли? Для случая Фибоначчи все ключи являются смежными, так что вектор является подходящим, еще раз есть гораздо более быстрые способы вычисления последовательности Фибоначчи, см. Мой пример кода там.