# PBinfo #1184 – Epuras – Rezolvare C++

Sursa: Codul lui Andrei
Limbaj: C++
Autor rezolvare: Darius

## Enunț

Cerința
Epur iepurașul dorește să epureze niște apă folosind stațiile de epurare aflate pe o câmpie de formă pătrată având latură n. Epur iepurașul începe să epureze de la stația de epurare aflată la coordonatele (1, 1). După ce apa epurată la stația de epurare de pe coordonatele (x, y) e pură, Epur se va deplasa la o stație care are ambele coordonate mai mari sau egale cu coordonatele curente. Epur Iepurașul este obligat de Legea Epurării pentru Iepuri să epureze și la stația situată la coordonatele (n, n).

Se știe că fiecare stație de epurare oferă un grad de puritate număr întreg. Când Epur iepurașul își epurează apa la stația aflată la (x, y), gradul de puritate ale apei sale crește cu gradul oferit de stația de epurare folosită. 

Ajutați-l pe Epur Iepurașul ca, epurând apa sa la stațiile de epurare să obțină un grad de puritate maxim.

Date de intrare
Fișierul de intrare epuras.in conține pe prima linie numărul n, iar pe următoarele n linii n numere naturale separate prin spații reprezentând gradul de puritate al apei oferit de fiecare stație de epurare.

Date de ieșire
Fișierul de ieșire epuras.out va conține pe prima linie numărul S, reprezentând gradul de puritate maxim.

Restricții și precizări

1 ≤ n ≤ 1.000
-10.000 ≤ gradele de puritate ≤ 10.000
rezultatul nu va depăși 32 de biți cu semn
fiecare stație de epurare poate fi folosită cel mult o dată

Exemplu:
epuras.in

5
5 -2 3 4 6
3 -8 -10 8 4
2 5 2 3 4
-4 -2 -3 -1 -7
-7 -5 -6 -7 0
epuras.out

28
Explicație
(1, 1) -> (1, 3) -> (1, 4) -> (2, 4) -> (2, 5) -> (3, 5) -> (5, 5)

## Cod sursă C++

```cpp
#include <fstream>
using namespace std;
ifstream fin ("epuras.in");
ofstream fout ("epuras.out");
const int N = 1005, oo = -1e9;
int n, d[N][N], a[N][N], MAX[N][N];
int main() {
    fin >> n;
    for (int i = 0; i <= n; ++i)
        for (int j = 0; j <= n; ++j)
            d[i][j] = MAX[i][j] = oo;
    for (int i = 1; i <= n; ++i)
        for (int j = 1; j <= n; ++j)
            fin >> a[i][j];
    d[1][1] = a[1][1];
    MAX[1][1] = d[1][1];
    for (int i = 1; i <= n; ++i)
        for (int j = 1; j <= n; ++j)
            if (!(i == 1 && j == 1)) {
                d[i][j] = max(MAX[i-1][j], MAX[i][j-1]) + a[i][j];
                MAX[i][j] = max(d[i][j], max(MAX[i-1][j], MAX[i][j-1]));
            }
    fout << d[n][n];
}
```

## Resurse

- [Pagina originală](https://codulluiandrei.ro/rezolvari/pbinfo/1184)
- [Sursa C++](https://codulluiandrei.ro/rezolvari/pbinfo/1184/cod.cpp)
- [Sursa pe GitHub](https://raw.githubusercontent.com/codulluiandrei/pbinfo/main/pbinfo-1184/main.cpp)
- [Cursuri de informatică pentru BAC](https://codulluiandrei.ro/academia/info-curs/pachet-cpp/)
