Sunteți pe pagina 1din 2

Generarea partiţiilor unui număr natural

Enunţ. Se citeşte un număr natural n. Se cere să se tipărească toate modurile de descompunere a


lui ca sumă de numere naturale. De exemplu, pentru n=4, avem: 4, 31, 22, 211, 13, 121, 112, 1111.
Ordinea numerelor din sumă este importantă. Astfel, se tipăreşte 112 dar şi 211, 121.
Rezolvare. De la început, observăm că nu se cunoaşte lungimea unei soluţii. Ea poate fi cuprinsă
între 1, în cazul în care numărul în sine constituie o descompunere a sa şi n, atunci când numărul este
descompus ca sumă a n numere egale cu 1.
Trecem la stabilirea algoritmului pe care îl vom folosi.
1. Fiecare componentă a vectorului x trebuie să reţină o valoare mai mare sau egală cu 1.
2. Mai întâi să observăm că, în procesul de generare a soluţiilor, trebuie ca în permanenţă să fie
respectată relaţia
x[1]+ x[2]+... x[k]≤n.
3. Avem soluţie atunci când
x[1]+ x[2]+... x[k]=n.
Rezultă de aici că trebuie să cunoaştem, la fiecare pas k, suma
s = x[1]+ x[2]+... x[k-1].
O primă posibilitate ar fi ca la fiecare pas să calculăm această sumă. Dar, se poate lucra eficient. Suma
va fi reţinută în permanenţă într-o variabilă globală, numită s.
Mai jos, este prezentată funcţionarea algoritmului pentru n=4:

Observaţi modul în care calculăm suma la fiecare pas. De câte ori se trece la componenta următoare
(k+1), la s se adună x[k], de câte ori se face pasul înapoi (se trece la componenta k-1), din s se
scade x[k].

Programul este prezentat în continuare:

#include <iostream>
using namespace std;
int x[100], n, i, s;
void back(int k)
{
if(s == n)
{
for(i = 1; i <= k - 1; i ++)
cout << x[i] << " ";
cout << "\n";
} else
{
x[k] = 0;
while(x[k] + s < n)
{
x[k] ++;
s = s + x[k];
back(k + 1);
s = s - x[k];
}
}
}
int main()
{
cin >> n;
back(1);
return 0;
}

for(int i = 1; i <= n - k + 1; i ++)


{
x[k] = i;
if(valid(k))
{
if(s == n) afis(k);
else back(k + 1);
}
}
}

int main()
{
f >> n;
back(1);
return 0;
}