suma in triunghi

2
2. Sumă în triunghi Sa considerăm un triunghi format din n linii (1<n100), fiecare linie conţinând numere întregi din domeniul [1,99], ca în exemplul următor: 7 3 8 8 1 0 2 7 4 4 4 5 2 6 5 Problema constă în scrierea unui program care să determine cea mai mare sumă de numere aflate pe un drum între numărul de pe prima linie şi un număr de pe ultima linie. Fiecare număr din acest drum este situat sub precedentul, la stânga sau la dreapta acestuia. (IOI, Suedia 1994) Soluţie 1. Vom reţine triunghiul într-o matrice pătratică T, de ordin n, sub diagonala principală. Subproblemele problemei date constau în determinarea sumei maxime care se poate obţine din numere aflate pe un drum între numărul T[i][j], până la un număr de pe ultima linie, fiecare număr din acest drum fiind situat sub precedentul, la stânga 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ă calculăm 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 reţine soluţiile subproblemelor, vom utiliza o matrice suplimentară S, pătratică de ordin n, cu semnificaţia S[i][j]= suma maximă ce se poate obţine pe un drum de la T[i][j] la un element de pe ultima linie, respectand condiţiile problemei. Evident, soluţia problemei va fi S[1][1]. 3. Relaţia 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. Rezolvăm relaţia 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]);} Exerciţiu Afişaţi şi drumul în triunghi pentru care se obţine soluţia optimă.

Upload: maglasu-ionut

Post on 03-Dec-2015

212 views

Category:

Documents


0 download

DESCRIPTION

suma in triunghi

TRANSCRIPT

Page 1: Suma in Triunghi

2. Sumă în triunghi

Sa considerăm un triunghi format din n linii (1<n100), fiecare linie conţinând numere întregi

din domeniul [1,99], ca în exemplul următor:

7

3 8

8 1 0

2 7 4 4

4 5 2 6 5

Problema constă în scrierea unui program care să determine cea mai mare sumă de numere aflate

pe un drum între numărul de pe prima linie şi un număr de pe ultima linie. Fiecare număr din acest

drum este situat sub precedentul, la stânga sau la dreapta acestuia. (IOI, Suedia 1994)

Soluţie

1. Vom reţine triunghiul într-o matrice pătratică T, de ordin n, sub diagonala principală.

Subproblemele problemei date constau în determinarea sumei maxime care se poate obţine din

numere aflate pe un drum între numărul T[i][j], până la un număr de pe ultima linie, fiecare

număr din acest drum fiind situat sub precedentul, la stânga 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ă calculăm 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 reţine soluţiile subproblemelor, vom utiliza o matrice suplimentară S, pătratică de ordin n,

cu semnificaţia

S[i][j]= suma maximă ce se poate obţine pe un drum de la T[i][j] la un element de pe

ultima linie, respectand condiţiile problemei.

Evident, soluţia problemei va fi S[1][1].

3. Relaţia 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. Rezolvăm relaţia 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]);}

Exerciţiu

Afişaţi şi drumul în triunghi pentru care se obţine soluţia optimă.

Page 2: Suma in Triunghi

Programul C++

1. #include<fstream> 2. #include<iostream> 3. using namespace std; 4. 5. int n,m,T[101][101],S[101][101]; 6. fstream fin("triunghi.in",ios::in), 7. fout("triunghi.out",ios::out); 8. 9. void citire() 10. { 11. int i,j; 12. fin>>n; 13. for(i=1;i<=n;i++) 14. for(j=1;j<=i;j++) 15. { 16. fin>>T[i][j]; 17. } 18. } 19. 20. void triunghi() 21. { 22. int i,j; 23. for (i=1; i<=n; i++) 24. S[n][i]=T[n][i]; 25. for (i=n-1; i>0; i--) 26. for (j=1; j<=i; j++) 27. { 28. S[i][j]=T[i][j]+S[i+1][j]; 29. if (S[i+1][j]<S[i+1][j+1]) 30. S[i][j]=T[i][j]+S[i+1][j+1]; 31. } 32. } 33. 34. void tipar() 35. { 36. int i,j; 37. for(i=1;i<=n;i++) 38. { 39. for(j=1;j<=i;j++) 40. cout<<S[i][j]<<" "; 41. cout<<endl; 42. } 43. } 44. int main () 45. { 46. citire(); 47. triunghi(); 48. tipar(); 49. fout<<S[1][1]; 50. fin.close(); 51. fout.close(); 52. return 0; 53. }