Cod sursa(job #3339431)

Utilizator maxtraAlex Deonise maxtra Data 8 februarie 2026 09:00:40
Problema Subsir crescator maximal Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.3 kb
#include <fstream>
#define DIM 100010
using namespace std;
/*
v[i] = elementele sirului
d[i] = lungimea maxima a unui subsir crescator care se termina exact in i
t[i] = "tata" lui i in resconstructie
        adica pozitia anterioara din subsirul optim care se termina in i
        */
int v[DIM], t[DIM];
int d[DIM];
int n, i, j, maxim, sol, p, u;
// maxim = cea mai buna valoare d[j] gasita pentru un i dat
// sol = lungimea maxima (raspunsul final)
// p = pozitia j care a dat "maxim" pentru i (parintele curent)
// u = pozitia unde se termina subsirul optim (pentru reconstructie)
ifstream fin ("scmax.in");
ofstream fout("scmax.out");
/* functie de reconstructie prin recursie
primeste u pozitia curenta din subsirul optim
daca u != 0, atunci reconstruim prefixul drum[t[u]]
apoi afisam v[u]
astfel elemenetele se afiseaza in ordine cresscatoare pe pozitii
*/
void drum(int u) {
    if (u!=0) {
        // 0 inseamna ca nu mai exista parinte, deci s a ajuns la inceputul subsirului
        drum(t[u]);
        fout<<v[u]<<" ";
    }
}
int main () {
    fin>>n;
    for (i=1;i<=n;i++)
        fin>>v[i];
    d[1] = 1;
    for (i=2;i<=n;i++) {
        maxim = 0;
        for (j=1;j<i;j++)
        // conditie pentru a putea continua un subsir crescator
        // v[j] < v[i]: putem pune v[i] dupa v[j]
        // d[j] > maxim: vrem cel mai lung subsir care se termina in j
        if (v[j] < v[i] && d[j] > maxim) {
            maxim = d[j];
            p = j; // salvez parintele
        }
        // daca am gasit un j valid, atunci asta
        // daca nu am gasit nimic, maxim ramane 0, deci d[i] = 1
        d[i] = maxim + 1;
        
        // setam parintele pentru reconstructie
        // daca d[i] = 1, inseamna ca v[i] porneste un subsir nou, fara parinte
        if (d[i] != 1)
            t[i] = p; // p este pozitia anterioara in subsir
        else
            t[i] = 0; // nu are parinte
            
        // actualizam solutia globala 
        // daca dp-ul de la i este mai bun, memoram:
        //  sol: lungimea maxima
        //  u: pozitia unde se termina subsirul optim
        if (d[i] > sol) {
            sol = d[i];
            u = i;
        }
    }
    
    fout<<sol<<"\n";
    
    // reconstruim si afisam un subsir crescator maximal
    // pornind de la u si urcand pe lantul de tati
    drum(u);
    
    return 0;
}