Triunghiul lui Pascal este un tablou triunghiular cu numere naturale, în care fiecare element aflat pe laturile triunghiului are valoarea 1, iar celelalte elemente sunt egale cu suma celor două elemente vecine, situate pe linia de deasupra.

Forma matriceală
El poate fii rearanjat pentru stocarea în matrice astfel:

În forma matriceală el poate fii calculat ca:
De fapt, aceasta este relația din cazul combinărilor:
Sau tradus pentru matricea noastră folosind i și j:
- Elementele de pe linia
nsunt coeficienți binomiali ai binomului lui Newton - Suma elementelor de pe linia
neste egală cu - Dacă considerăm matricea noastră ma fiind
tp[m][m], va fii stocat întp[n][k]
Generarea combinărilor folosind triunghiul lui Pascal
Evident pentru a genera combinările putem folosi metoda recursivă și putem aplica memoizarea pentru a o face mai eficientă. Totuși pentru a aplica programarea dinamică, vom folosi forma matriceală a triunghiului lui Pascal.
Cod
Varianta cu toată matricea
Pentru a calcula folosind Triunghiul lui Pascal urmăm pașii:
- Populăm prima coloană și diagonala principală cu valoarea 1
- Parcurgem începând cu
i=2(primele 2 rânduri sunt deja complete) șij=1(prima coloană este completă) matricea. - Parcurgem rândul cât timp
j<i(înainte de diagonala principală, care este deja umplută) - Ne oprim când
i>n(trecem rândul pe care se află )- Pe poziția
tp[i][j]punem suma dintre valoarea direct de deasupratp[i-1][j], și cea din stânga celei de sustp[i-1][j-1](tp[i][j] = tp[i-1][j-1] + tp[i-1][j]) În această rezolvare stocăm foarte multe date care nu sunt necesare, deși nu folosim decât linia anterioară, avem o complexitate de spațiu
- Pe poziția
#include <iostream>
using namespace std;
int tp[10][10];
int pascal(int n, int k){
for(int i = 0; i <= n; ++i){
tp[i][0] = tp[i][i] = 1;
}
for(int i = 2; i <= n; ++i){
for(int j = 1; j < i; ++j){
tp[i][j] = tp[i-1][j-1] + tp[i-1][j];
}
}
return tp[n][k];
}
int main(){
int n, k;
cin >> n >> k;
cout << pascal(n, k);
}Varianta cu un singur vector
Totuși putem observa că în calcularea unui element folosim doar rândul anterior, nu și celelalte. Deci putem face soluția mai eficientă privind spațiul folosind un singur vector peste care scriem de mai multe ori. Trebuie să ținem cont de elementele folosite în calcul deoarece în calculul lui folosim și , dar ar fii modificat în dacă am face generarea de la stânga la dreapta. Așa că vom genera combinările de la dreapta la stângă, păstrând astfel valorile de care avem nevoie (cea curentă și cea de la stânga) intacte cât timp avem nevoie de ele. Folosind doar un vector, complexitatea de spațiu ajunge la doar . La aceasta variantă nu mai există îmbunătățiri posibile.
Varianta iterativă
În această variantă la orice moment dat
Deci, în level știm rândul pe care ne aflăm din forma matriceală a triunghiul lui Pascal, iar în i știm coloana
c[level+1] este întotdeauna 1 pentru că indexarea începe de la 1
#include <iostream>
using namespace std;
void pascal(int niv, int c[]){
int level = 1;
c[1] = c[2] = 1;
while(level < niv){
level++;
c[level + 1] = 1;
for(int i = level; i >= 2; i--)
c[i] += c[i-1];
}
}
int main(){
int c[1001], n, k;
cin >> n >> k;
pascal(n, c);
cout << c[k];
return 0;
}Varianta recursivă
În această variantă la orice moment dat
Deci, în niv știm rândul pe care ne aflăm din forma matriceală a triunghiul lui Pascal, iar în i știm coloana
c[niv+1] este întotdeauna 1 pentru că indexarea începe de la 1.
Înainte de generarea liniei curente, apelăm pascal(niv-1, a) pentru a genera linia anterioară. Acest proces se oprește când niv==1, adică linia pe care sunt stocate și
#include <iostream>
using namespace std;
void pascal(int niv, int a[]){
if(niv == 1){
a[1] = a[2] = 1;
return;
}
pascal(niv - 1, a);
for(int i = niv; i >= 2; i--)
a[i] += a[i-1];
a[niv + 1] = 1;
}
int main(){
int a[1001], n, k;
cin >> n >> k;
pascal(n, a);
cout << a[k];
return 0;
}Varianta aceasta s-a dat și în 2019 la admiterea de la UBB: Generarea Triunghiul lui Pascal fără structuri de date bidimensionale