Числа на Фибоначи
* Числа на Фибоначи: F(0) = F(1)= 1 и F(i)
= F(i-1) + F(i-2) за i > 1.
* Динамично програмиране - със запомняне на вече пресметнатите стойности:
#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-тото число на Фибоначи
е: %lu", n, fibMemo(n));
return 0;
}
Линейна сложност.
* Друга формула за пресмянате на n-тото число на Фибоначи - със запомняне на вече пресметнате стойност.
F(n) = F2(n/2) + F2(n/2 - 1), за n четно;#include <stdio.h>
F(n) = F(n-1) + F(n - 2), за n нечетно.
unsigned long fMemo(unsigned n)
{ if (n<2) m[n] = 1;
else if (0 == m[n])
if (1 == n%2)
m[n] = fMemo(n-1) + fMemo(n-2);
else m[n] = SQR(fMemo(n/2)
+ fMemo(n/2-1));
return m[n];
}
int main()
{ memset(m, 0, MAX*sizeof(*m));
scanf("%u", &n);
printf("\n%u-тото число на Фибоначи
е: %lu", n, fibMemo(n));
return 0;
}
Логаритмична сложност.
Нека C(n, k) е биномният коефициент "n над k" или комбинации без повторения от n елемента k-ти клас. Общата формула е: C(n, k) = n!/((n - k)! k!), а от триъгълника на Паскал имаме и рекурентна формула:
* Динамично програмиране - със запомняне на вече пресметнатите стойности.
Не е необходимо да се пази цялата таблица
C(n, k), а само един ред от таблицата - предишния.
#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];
}
Пример: n = 4, k
= 3; C(4,3) = 4.
i | j | m
0 1 2 3 4 |
0 | - | 1 1 1 1 1 |
1 | - | 1 1 1 1 1 |
2 | 1 | 1 2 1 1 1 |
3 | 2 | 1 3 3 1 1 |
4 | 3 | 1 4 6 4 1 |