Sunteți pe pagina 1din 2

2.

Sum n triunghi
Sa considerm un triunghi format din n linii (1<n100), fiecare linie coninnd numere ntregi
din domeniul [1,99], ca n exemplul urmtor:
7
3
8
2
4

8
1

7
5

0
4

4
6

Problema const n scrierea unui program care s determine cea mai mare sum de numere aflate
pe un drum ntre numrul de pe prima linie i un numr de pe ultima linie. Fiecare numr din acest
drum este situat sub precedentul, la stnga sau la dreapta acestuia. (IOI, Suedia 1994)
Soluie
1. Vom reine triunghiul ntr-o matrice ptratic T, de ordin n, sub diagonala principal.
Subproblemele problemei date constau n determinarea sumei maxime care se poate obine din
numere aflate pe un drum ntre numrul T[i][j], pn la un numr de pe ultima linie, fiecare
numr din acest drum fiind situat sub precedentul, la stnga sau la dreapta sa. Evident,
subproblemele nu sunt independente: pentru a calcula suma maxim a numerelor de pe un drum de
la T[i][j] la ultima linie, trebuie s calculm suma maxim a numerelor de pe un drum de la
T[i+1][j] la ultima linie i suma maxim a numerelor de pe un drum de la T[i+1][j+1] la
ultima linie.
2. Pentru a reine soluiile subproblemelor, vom utiliza o matrice suplimentar S, ptratic de ordin n,
cu semnificaia
S[i][j]= suma maxim ce se poate obine pe un drum de la T[i][j] la un element de pe
ultima linie, respectand condiiile problemei.
Evident, soluia problemei va fi S[1][1].
3. Relaia de recuren care caracterizeaz substructura optimal a problemei este:
S[n][i]=T[n][i], i{1,2,...,n}
S[i][j]=T[i][j]+max{S[i+1][j], S[i+1][j+1]}
4. Rezolvm relaia de recuren n mod bottom-up:
int i, j;
for (i=1; i<=n; i++) S[n][i]=T[n][i];
for (i=n-1; i>0; i--)
for (j=1; j<=i; j++)
{S[i][j]=T[i][j]+S[i+1][j];
if (S[i+1][j]<S[i+1][j+1])
S[i][j]=T[i][j]+S[i+1][j+1]);}

Exerciiu
Afiai i drumul n triunghi pentru care se obine soluia optim.

Programul C++
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.

#include<fstream>
#include<iostream>
using namespace std;
int n,m,T[101][101],S[101][101];
fstream fin("triunghi.in",ios::in),
fout("triunghi.out",ios::out);
void citire()
{
int i,j;
fin>>n;
for(i=1;i<=n;i++)
for(j=1;j<=i;j++)
{
fin>>T[i][j];
}
}
void triunghi()
{
int i,j;
for (i=1; i<=n; i++)
S[n][i]=T[n][i];
for (i=n-1; i>0; i--)
for (j=1; j<=i; j++)
{
S[i][j]=T[i][j]+S[i+1][j];
if (S[i+1][j]<S[i+1][j+1])
S[i][j]=T[i][j]+S[i+1][j+1];
}
}
void tipar()
{
int i,j;
for(i=1;i<=n;i++)
{
for(j=1;j<=i;j++)
cout<<S[i][j]<<" ";
cout<<endl;
}
}
int main ()
{
citire();
triunghi();
tipar();
fout<<S[1][1];
fin.close();
fout.close();
return 0;
}