* Числа на Фибоначи: F(0) = F(1) = 1 и F(i) = F(i -1) + F(i - 2) за i > 1.
Експоненциална сложност - многократно извикване на функцията с един и същи аргумент!unsigned long fib(unsigned n)
{ if (n < 2) return 1;
return fib(n - 1) + fib(n - 2);
}
* Динамично програмиране - със запомняне на вече пресметнатите стойности:
Линейна сложност - всяка стойност се пресмята само веднаж.#include <stdio.h>
#define MAX 256
unsigned n = 10;
unsigned long m[MAX + 1];
unsigned long fibMemo(unsigned n)
{ if (n < 2) m[n] = 1;
else if (0 == m[n]) m[n] = fibMemo(n - 1)+ fibMemo(n - 2);
return m[n];
}
int main()
{ memset(m, 0, MAX*sizeof(*m));
scanf("%u", &n);
printf("\n%u-тото число на Фибоначи e", %lu", n, fibMemo(n));
return 0;
}
Нека C(n, k) е биномният
коефициент
"n над k" или комбинации без повторения от n
елемента
k-ти клас.
Общата формула е: C(n, k)
= n!/((n - k)! k!), а от триъгълника на Паскал
имаме
и рекурентна формула:
* Рекурсивен неефективен алгоритъм:
unsigned long binom(unsigned n, unsigned k)
{ if (k > n) return 0;
if (k == 0 || k == n) return 1;
return binom(n - 1, k - 1) + binom(n - 1, k);
}
* Динамично програмиране - със запомняне на вече пресметнатите стойности. Не е необходимо да се пази цялата таблица C(n, k), а само един ред от таблицата - предишния.
Пример: n = 5, k = 3; C(5,3) = 10.#define MAX 200
unsigned long m[MAX];
unsigned long binomDynam(unsigned n, unsigned k)
{ unsigned i, j;
for (i = 0; i <= n; i++)
{ m[i] = 1;
if (i > 1)
{ if (k < i - 1) j = k; else j = i - 1;
for (; j >= 1; j--) m[j] += m[j - 1];
}
}
return m[k];
}
i | k<i-1 |
начално j | m 0 1 2 3 4 |
0 | - |
- | 1 1 1 1 1 |
1 | - |
- | 1 1 1 1 1 |
2 | 3<2-1 |
1 |
1 2 1 1 1 |
3 | 3<3-1 |
2 | 1 3 3 1 1 |
4 | 3<4-1 |
3 | 1 4 6 4 1 |
5 |
3<5-1 |
3 |
1 5 10 10 5 |
Задача 4a. Числа на Фибоначи
Да се напише програма (4a.cpp
или 4a.c)
за пресмятане на n-тото
число на Фибоначи със запомняне
на вече пресметнати стойности и използване на формулата:
F(n) = F2(n/2) + F2(n/2 - 1), за n четно; F(n) = F(n - 1) + F(n - 2), за n нечетно.Да се намери най-голямото n, за което написаната програма пресмята вярно F(n). (Логаритмична сложност.)
Пример за вход 10 4 p 1 Helga n 3 Joanna p 5 Venus n 7 Clever 0 0 |
Изход - решение на примерния вход 9 Venus |