Sunteți pe pagina 1din 10

Şiruri de tip Fibonacci

Sirul lui Fibonacci este o secventa de numere in care fiecare numar se obtine din
suma precedentelor doua din sir. Astfel, primele 10 numere ale sirului lui Fibonacci sunt:
1, 1, 2, 3, 5, 8, 13, 21, 34, 55, ...
(primele 2 numere sunt predefinite, iar restul se obtin in mod recursiv, din suma
precedentelor doua: 3 = 2 + 1, 5 = 3 + 2, samd...)

Secventa numerelor lui Fibonacci a fascinat de-a lungul istoriei pe foarte multi oameni de
stiinta, matematicieni, fizicieni, biologi, si, continua sa o faca chiar si in prezent.

Problema iepurilor
Fiind dată o pereche de iepuri, se ştie că fiecare pereche de iepuri produce în fiecare
lună o nouă pereche de iepuri, care la rândul său devine productivă la vârsta de o lună. Să
se determine câte perechi de iepuri vor fi după n luni.

Leonardo din Pisa, cunoscut sub numele Fibonacci (prescurtare de


la filius Bonacci – adică “fiul celui bun”) este cel care a folosit acest şir
pentru a rezolva problema iepurilor.

Fibonacci, născut în Italia, în 1175, a fost educat în Nordul Africii,


unde tatăl său deţine un post diplomatic. Revenind în Italia, în 1202
publică un tratat de matematică cu titlul "Liber abaci". Acest tratat
conţine aproape toată informaţia acelui timp, referitoare la aritmetică şi
algebră, şi care a avut un rol important pe parcursul următoarelor secole în dezvoltarea
matematicii în Europa. În particular, în baza acestui tratat, europenii au luat cunoştinţă de
scrierea arabică a numerelor, adică de sistemul de numeraţie poziţional arab, care este cel
folosit şi în zilele noastre. La fel, în 1220 publică "Practica geometrica", în 1225 "Liber
quadratorum". Tratatul "Liber abaci" a fost reeditat în 1228. Una din problemele discutate
in "Liber abaci" este "problema iepurilor", (p. 123-124 in editia anului 1228).
Numele lui Fibonacci apare, prin extindere, în denumirea unor structuri de date (heap
Fibonacci) sau metode de programare (căutare Fibonacci).

1. Rezolvarea matematică a recurenţei

Formal, şirul este definit prin următoarea recurenţă:


(1) fn=fn-1+fn-2, unde
(2) f0=0 şi f1=1

Pentru a găsi forma generală a şirului, presupunem că:


(3) fn=λn.
unde λ este un parametru real.
Substituim (3) în (1) şi obţinem:
λn= λn-1 +λn-2,
sau echivalent
λn(λ2 -λ-1)=0.

1
Cum fn≠0, ultima egalitate devine:
(4) λ2 -λ-1=0
adică o ecuaţie pătratică în raport cu parametrul real λ, cu soluţiile:

Şirurile de forma

verifică egalitatea (1). De aici deducem că ecuaţia de forma (1) posedă mai multe soluţii
(o infinitate). Se verifică uşor că toate şirurile de forma:

unde c1,c2 sunt constante reale fixate, verifică recurenţa (1).


Folosind valorile iniţiale din (2), obţinem că:

cu soluţia :

În general, termenul de rang n din şirul de Fibonacci are forma:

2. Probleme rezolvate

1. Scara. În câte moduri diferite poate să urce un om pe o scară cu n trepte, dacă el


poate urca una sau două trepte odată?
Soluţie: Notăm cu F[n] numărul căutat. Avem pentru n=1, F[1]=1 (urcă o singură
treaptă) iar dacă n=2, F[2]=2, adică urcă (1) 1+1 sau (2) 2 trepte. Pentru a ajunge la
nivelul n, adică F[n], Gigel poate urca ultima dată o treaptă sau două trepte. Deci,
F[n]=F[n-1]+F[n-2], cu F[1]=1, F[2]=2. Soluţia problemei este termenul de rang n+1 al
şirului lui Fibonacci.
Diagrama de mai jos prezintă toate posibilităţile de a urca o scară cu n=4 trepte.
Semnul X indică treapta care a fost folosită la un pas.

2
2. Scara 2. Georgel vrea să ştie în câte moduri diferite poate să urce o scară cu n trepte,
dacă poate urca una sau k trepte odată, unde k este dat. De exemplu, când k=3, Georgel
urcă una sau trei trepte odată.
Soluţie: Pentru a ajunge la nivelul n, se poate urca de la nivelul n-1 sau n-k. În acest caz
relaţia de recurenţă este F[n]=F[n-1]+F[n-k]. Rămâne să stabilim care sunt valorile
iniţiale. Astfel, avem că F[1]=1, F[2]=1,…,F[k-1]=1 şi F[k]=2. Rezultă că
F[k+1]=F[k]+F[1]=3,ş.a.m.d.

3. Scara 3. Georgel vrea să ştie în câte moduri diferite poate să urce o scară cu n trepte,
dacă poate urca una sau k trepte odată, unde k este dat. Din cauza efortului depus, după
ce a urcat k trepte poate să urce numai una, după care poate continua cu 1 sau k trepte.
De exemplu, când n=5, k=2, Georgel are posibilităţile (1,1,1,1,1), (1,1,1,2), (1,1,2,1),
(1,2,1,1), (2,1,1,1), (2,1,2), deci în total 6 modalităţi.

Soluţie: La fel ca la problema anterioară, pentru a ajunge la nivelul n, Georgel poate urca
ultima dată 1 sau k trepte odată. În cazul în care ultima dată a urcat k trepte, înseamnă
că înainte de acestea a urcat o singură treaptă (altfel nu se mai respectă cerinţele
problemei !), deci vine de la nivelul n-k-1. Obţinem relaţia de recurenţă:
F[n]=F[n-1]+F[n-k-1], pentru n>k,iar valorile iniţiale sunt F[i]=1, pentru i=1,…,k-1 şi
F[k]=2.

4. Blocuri. Georgel are o bandă de dimensiuni 1xn pe care vrea să o acopere cu blocuri
de tip 1x1 negre şi 1x3 roşii. Câte modalităţi de aranjare a blocurilor există?

Soluţie: Este aceeaşi relaţie de recurenţă de la scara 2: F[n]=F[n-1]+F[n-k] cu n>k şi


aceleaşi condiţii iniţiale.

3
5. Blocuri 1-3. Georgel are o bandă de dimensiuni 1xn pe care vrea să o acopere cu
blocuri de tip 1x1 negre şi 1x3 roşii, astfel încât oricare două blocuri roşii (care pot fi de
orice lungime) să fie separate de cel puţin un bloc negru. Câte modalităţi de aranjare a
blocurilor există?
Soluţie: Este aceeaşi relaţie de recurenţă de la scara 3: F[n]=F[n-1]+F[n-k-1] şi aceleaşi
condiţii iniţiale.

6. Blocuri 1-2-3. Georgel are o bandă de dimensiuni 1xn pe care vrea să o acopere cu
blocuri de tip 1x1 negre, 1x2 verzi şi 1x3 albastre. Câte modalităţi de aranjare a blocurilor
există?

Soluţie: Notăm cu F[n] numărul de posibilităţi de acoperire cerut în enunţ. Ultimul bloc
adăugat poate fi oricare tip de bloc, astfel că din restricţiile impuse rezultă relaţia de
recurenţă: F[n]=F[n-1]+F[n-2]+F[n-3] cu condiţiile iniţiale F[1]=1, F[2]=2, F[3]=3.
Aceste numere sunt cunoscute sub numele de numere Tribonacci.

Termenul Explicaţie

F[1]=1 Condiţii iniţiale: 1

F[2]=2 Condiţii iniţiale: 1-1,2

F[3]=4 Condiţii iniţiale: 1-1-1,1-2,2-1,3

F[4]=F[3]+F[2]+F[1]=7 1-1-1-1, 1-1-2, 1-2-1, 2-1-1, 2-2, 1-3, 3-1

F[5]=F[4]+F[3]+F[2]=13 1-1-1-1-1, 1-1-1-2, 1-1-2-1, 1-2-1-1, 2-1-1-1,


1-2-2, 2-1-2, 2-2-1, 1-1-3, 1-3-1, 3-1-1, 2-3, 3-2

Mai jos sunt reprezentate toate acoperirile posibile pentru o banda de lungime 5:

4
7. X şi O. Fie S[n] o secvenţă de n caractere construită numai din simbolurile X şi O astfel
încât să nu apară două simboluri O alăturate. Care este numărul de secvenţe S[n]?
Soluţie: Notăm cu F[n] numărul de secvenţe. Construim primele secvenţe şi obţinem:

Termenul Explicaţie

F[1]=2 Condiţii iniţiale: X, O

F[2]=3 Condiţii iniţiale: XX, XO, OX

F[3]=5 XXX, XXO, XOX, OXX, OXO

Din modul de construire a şirurilor S[n] se observă că toate se obţin din şiruri care încep
cu prefixul X sau OX şi respectă recurenţa lui Fibonacci F[n]=F[n-1]+F[n-2], cu valorile
iniţiale F[1]=2, F[2]=3.

8. Domino 1. O tablă dreptunghiulară de tip 1xn este acoperită folosind piese de domino
de dimensiuni 1x2 şi pătrate de tip 1x1. Câte modalităţi de acoperire a tablei există?

Soluţie: Din primele acoperiri se observă că numărul acestea sunt 1, 2, 3, 5 adică


numerele căutate sunt numerele lui Fibonacci.

5
9. Domino 2. O tablă dreptunghiulară de tip 2xn este acoperită folosind piese de domino
de dimensiuni 1x2 sau 2x1. Câte modalităţi de acoperire a tablei există?

Soluţie: Notăm cu F[n] numărul de acoperiri ale unei table de tip 2xn. Avem F[1]=1,
F[2]=2. În general, dacă la sfârşit apare o piesă verticală, numărul de acoperiri este dat
de F[n-1] iar dacă apar două piese aşezate orizontal, numărul de acoperiri este F[n-2].

10. Domino 2xn. O tablă dreptunghiulară de tip 2xn este acoperită folosind piese de
domino de dimensiuni 1x2 (de culoare roşie) şi pătrate 2x2 (de culoare galbenă). Câte
posibilităţi de acoperire a tablei există?

Soluţie: Notăm cu F[n] numărul căutat. Ultima coloană poate fi acoperită de un domino
vertical, cu F[n-1], sau un pătrat. Pătratul poate fi format în două moduri: un pătrat 2x2
sau din două dominouri orizontale. Posibilităţile în care dominourile sunt plasate vertical a
fost deja numărate în F[n-1]. Relaţia de recurenţă este F[n]=F[n-1]+2*F[n-2]. Valorile
iniţiale sunt F[1]=1 şi F[2]=3, iar F[3]=5, F[4]=11.

3. Variante de implementare în limbajul C++


1) Varianta recursivă, este uşor de scris dar ineficientă:
1. long Fib(long n)
2. {
3. if(n==0)||(n==1)return n;
4. else return Fib(n-1)+Fib(n-2); //aplicăm formula de recurenţă
5. }

2) În cazul apelului recursiv se ajunge ca unele valori să se calculeze de mai multe ori,
prin ramificarea apelurilor recursive. Eliminarea calculelor redundante se poate face prin
tehnica memoizării care duce la calcularea eficientă a valorilor din şirul lui Fibonacci.
Dezavantajul acestei metode este acela că foloseşte un spaţiu de memorie care depinde
de n, adică O(n).

1. long F[50];//vector global (iniţializat cu 0)


2.
3. long Fib(long n)
4. {
5. if(n==0)||(n==1)return n;
6. if (F[n]>0) return F[n]; //dacă valoarea a fost deja calculată o returnăm
7. else return Fib(n-1)+Fib(n-2); //aplicăm formula de recurenţă
8. }

6
3) Varianta iterativă, folosind vectori este eficientă ca timp, dar consumă un spaţiu de
memorie în funcţie de n, O(n):

1. long F[50];//vector global (iniţializat cu 0)


2.
3. long Fib(long n)
4. {
5. int i;
6. F[0]=0;
7. F[1]=1;
8. for(i=2;i<=n;i++)
9. F[i]=F[i-1]+F[i-2];//aplicam relatia de recurenta
10. return F[n];
11. }

4) Varianta iterativă optimă foloseşte memorie constantă, declarăm doar 3 variabile


întregi a,b,c. Acestea corespund celor trei valori din definiţia recursive a şirului:

1. long Fib(long n)
2. {
3. long i,a,b,c;
4. if(n<=1)return n;
5. a=0;
6. b=1;
7. for(i=2;i<=n;i++)
8. {
9. c=a+b;
10. a=b;
11. b=c;
12. }
13. return c;
14. }

5) Varianta iterativă cu memorie constantă poate fi scrisă folosind doar variabilele a


şi b:

1. long Fib(int n)
2. {
3. long i,a,b;
4. if(n<=1)return n;
5. a=0;b=1;
6. for(i=2;i<=n;i++)
7. {
8. b=a+b;
9. a=b-a;
10. }
11. return b;
12. }

7
6) Varianta iterativă poate fi folosită pentru calcularea termenilor şirului lui Fibonacci
folosind operaţiile cu numere mari:

1. void Fib(long n,long a[100001],long b[100001],long c[100001])


2. {
3. int i;
4. a[0]=1;a[1]=0;//initializarea lui a
5. b[0]=1;b[1]=1;//initializarea lui b
6.
7. for(i=2; i<=n; i++)
8. { add(a,b,c);//c=a+b
9. copiere(a,b);//a=b
10. copiere(b,c);//b=c
11. }
12. return; //rezultatul este in vectorul c
13. }

7) Termenii şirului lui Fibonacci pot fi evaluaţi mai rapid, în timp logaritmic O(log 2n),
folosind metoda matricială. Scriem relaţiile de recurenţă dintre termenii şirului sub forma:
fn+1 = fn + fn-1
fn = fn-1+ fn-2

Aceste ecuaţii pot fi scrise sub forma matriceală

 Fn 1 Fn  1 1  Fn Fn 1 
F  
 n Fn 1  1 0  Fn 1 Fn 2 
iar prin inducţie matematică se demonstrează că:

n
 Fn 1 Fn  1 1 1 1
F     M n , unde M   
 n Fn 1  1 0 1 0

Ridicarea la puterea n a matricii M poate fi făcută în timp logaritmic, O(log2n), ceea ce


reduce semnificativ timpul de calcul pentru valori mari ale rangului n.

Puterea x poate fi calculată în timp logaritmic folosind metoda Divide et Impera:


n

 1, dacă n  0

x   x  ( x ) , dacă n  2k  1
n k 2

 (xk )2 , dacă n  2k

1. long long P(long a,long b)


2. { long long p=a,r=1;
3. while(b>0)
4. { if(b%2==1)r=r*p;
5. b=b/2;
6. p=p*p;
7. }
8. return r;
9. }
8
Valoarea primelor 100 de termeni ai şirului lui Fibonacci sunt:
n F[n] n F[n]
0 0 51 20365011074
1 1 52 32951280099
2 1 53 53316291173
3 2 54 86267571272
4 3 55 139583862445
5 5 56 225851433717
6 8 57 365435296162
7 13 58 591286729879
8 21 59 956722026041
9 34 60 1548008755920
10 55 61 2504730781961
11 89 62 4052739537881
12 144 63 6557470319842
13 233 64 10610209857723
14 377 65 17167680177565
15 610 66 27777890035288
16 987 67 44945570212853
17 1597 68 72723460248141
18 2584 69 117669030460994
19 4181 70 190392490709135
20 6765 71 308061521170129
21 10946 72 498454011879264
22 17711 73 806515533049393
23 28657  int 74 1304969544928657
24 46368 75 2111485077978050
25 75025 76 3416454622906707
26 121393 77 5527939700884757
27 196418 78 8944394323791464
28 317811 79 14472334024676221
29 514229 80 23416728348467685
30 832040 81 37889062373143906
31 1346269 82 61305790721611591
32 2178309 83 99194853094755497
33 3524578 84 160500643816367088
34 5702887 85 259695496911122585
35 9227465 86 420196140727489673
36 14930352 87 679891637638612258
37 24157817 88 1100087778366101931
38 39088169 89 1779979416004714189
39 63245986 90 2880067194370816120
40 102334155 91 4660046610375530309
41 165580141 92 7540113804746346429  long long
42 267914296 93 12200160415121876738
43 433494437 94 19740274219868223167
44 701408733 95 31940434634990099905
45 1134903170 96 51680708854858323072
46 1836311903  long 97 83621143489848422977
47 2971215073 98 135301852344706746049
48 4807526976 99 218922995834555169026
49 7778742049 100 354224848179261915075
50 12586269025

9
Cititorul interesat poate găsi extinderi şi probleme mai dificile
http://infoarena.ro/probleme-de-acoperire-1
http://infoarena.ro/probleme-de-acoperire-2

10

S-ar putea să vă placă și