Grade 11 · Dynamic programmingCitește în română
Maximum sum in a number triangle
Original: Suma maximă în triunghiul de numere
The idea
A triangle has n rows; row i holds i numbers. We start from the top and at every step go either straight down (a[i+1][j]) or down and to the right (a[i+1][j+1]). We want the maximum sum of the numbers on the path. We work from the bottom up: s[i][j] = a[i][j] + max(s[i+1][j], s[i+1][j+1]), and on the last row s[n][j] = a[n][j]. The answer is s[1][1]. The path is rebuilt from the top down, always moving to the child with the larger s (straight down, on ties).
Original description (Romanian)
Un triunghi are n linii; linia i conține i numere. Pornim din vârf și la fiecare pas coborâm fie drept în jos (a[i+1][j]), fie în jos și la dreapta (a[i+1][j+1]). Vrem suma maximă a numerelor de pe drum. Lucrăm de jos în sus: s[i][j] = a[i][j] + max(s[i+1][j], s[i+1][j+1]), iar pe ultima linie s[n][j] = a[n][j]. Răspunsul este s[1][1]. Drumul se reface de sus în jos, mergând mereu spre fiul cu s mai mare (drept în jos, la egalitate).
- Complexity
- O(n²) time and memory
- Grade
- Grade 11 (Clasa a XI-a)
- Chapter
- Dynamic programming
Examples
Input
4 5 4 6 2 9 1 8 3 5 7
Expected output
25 5 6 9 5
The code
Comments are in Romanian, as in the original collection. Edit freely: you can reset at any time.
/*
* Titlu: Suma maximă în triunghiul de numere
* Clasa: 11
* Capitol: Programare dinamică
* Descriere: Un triunghi are n linii; linia i conține i numere. Pornim din vârf și la
* fiecare pas coborâm fie drept în jos (a[i+1][j]), fie în jos și la dreapta
* (a[i+1][j+1]). Vrem suma maximă a numerelor de pe drum. Lucrăm de jos în sus:
* s[i][j] = a[i][j] + max(s[i+1][j], s[i+1][j+1]), iar pe ultima linie
* s[n][j] = a[n][j]. Răspunsul este s[1][1]. Drumul se reface de sus în jos,
* mergând mereu spre fiul cu s mai mare (drept în jos, la egalitate).
* Complexitate: O(n²) timp și memorie
*
* Exemplu
* Intrare:
* 4
* 5
* 4 6
* 2 9 1
* 8 3 5 7
* Ieșire:
* 25
* 5 6 9 5
*/
#include <iostream>
using namespace std;
int a[105][105], s[105][105];
int main()
{
int n;
cin >> n;
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= i; j++)
{
cin >> a[i][j];
}
}
for (int j = 1; j <= n; j++)
{
s[n][j] = a[n][j];
}
for (int i = n - 1; i >= 1; i--)
{
for (int j = 1; j <= i; j++)
{
s[i][j] = a[i][j] + max(s[i + 1][j], s[i + 1][j + 1]);
}
}
cout << s[1][1] << '\n';
int j = 1;
for (int i = 1; i <= n; i++)
{
cout << a[i][j] << ' ';
if (i < n && s[i + 1][j + 1] > s[i + 1][j])
{
j++;
}
}
cout << '\n';
return 0;
}
Runs on a real g++ (C++17, -O2) through Compiler Explorer. Keep runs short; there's a time limit.