Cod sursa(job #3350938)

Utilizator robert.stefanRobert Stefan robert.stefan Data 14 aprilie 2026 21:21:37
Problema Subsir crescator maximal Scor 60
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.5 kb
// https://www.infoarena.ro/problema/scmax

#include<fstream>

using namespace std;

ifstream fin("scmax.in");
ofstream fout("scmax.out");

int n;
int sir[100001];

// dp[i] memoreaza lungima maxima a subsirului crescator ce se incheie cu elementul i
int dp[100001];

// posMax reprezinta pozitia ultimului element care face parte din subsirul crescator de lungime maxima
// initial, posMax ia valoarea 0, adica cel mai lung subsir crescator este format doar din primul element al sirului
// (memorarea subsirului incepe de la pozitia 0)

// elementAnterior[i] reprezinta indexul in vectorul sir al elementului ce precede elementul sir[i] in subsirul crescator
// daca elementAnterior[i] == -1, atunci sir[i] este primul element al subsirului crescator (niciun element nu ii precede)
int elementAnterior[100001];

int posMax = 0;

void afisareSubsir(int index) {
	if(index < 0) {
		return; // daca am ajuns la un index negativ (-1), inseamna ca am afisat deja primul element al subsirului
	}

	afisareSubsir(elementAnterior[index]);

	fout << sir[index] << " ";
}

int main() {
	fin >> n;

	for(int i = 0; i < n; i++) {
		fin >> sir[i];
	}

	// primul element face parte dintr-un subsir crescator de lungime 1 (nu are niciun alt element in fata lui),
	// deci vom rula algoritmul de programare dinamica incepand cu al doilea element
	dp[0] = 1;

	for(int i = 1; i < n; i++) {
		// initial, lungimea subsirului ce se termina cu elementul sir[i] este 1 (subsirul care are doar pe sir[i] ca element),
		// iar niciun element nu ii precede in subsirul crescator
		dp[i] = 1;
		elementAnterior[i] = -1;


		// verificam in stanga elementului daca gasim elemente mai mici decat el
		for(int j = 0; j < i; j++) {
			if(sir[j] < sir[i]) {
				// daca am gasit un element mai mic decat el, atunci il putem adauga in subsirul crescator
				// iar lungima subsirului ce se termina cu sir[i] va fi egala cu lungimea subsirului ce se termina cu sir[j] + 1
				// doar ca putem gasi mai multe elemente mai mici decat sir[i], iar atunci vom alege elementul care ne ofera o lungime cat mai mare
				if(dp[i] < dp[j] + 1){
					dp[i] = dp[j] + 1;
					elementAnterior[i] = j;
				}
			}
		}

		// actualizam pozitia la care am gasit lugima maxima
		if(dp[posMax] < dp[i]) {
			posMax = i;
		} 
	}

	fout << dp[posMax] << endl;

	// ne folosim de recursivitate pentru a afisa in ordine crescatoare subsirul, pornind de la indexul ultimului element pana la indexul primului element din subsir
	afisareSubsir(posMax);

	fout << endl;

	fin.close();
	fout.close();

	return 0;
}