Cod sursa(job #3353210)

Utilizator robert.stefanRobert Stefan robert.stefan Data 5 mai 2026 16:20:28
Problema Subsir crescator maximal Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.26 kb
// https://www.infoarena.ro/problema/scmax

#include<fstream>

using namespace std;

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

int n;
int sir[100000];

// definirea starii (subproblemei):
// dp[i] - este lungimea maxima a subsirului strict crescator care se incheie cu elementul sir[i]
int dp[100000];

// elAnterior reprezinta indicele la care se afla elementul anterior elementului sir[i], 
// atunci cand concatenam pe sir[i] la un alt subsir strict crescator. 
int elAnterior[100000];

void afisareSubsir(int i) {
	if(i >= 0) {
		afisareSubsir(elAnterior[i]);

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

int main() {
	fin >> n;

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

	// Problema o vom rezolva cu programare dinamica astfel:
	// Parcurgem sirul de la primul element pana la ultimul element, folosind indicele i.
	// La fiecare indice i, consideram, initial, ca cel mai lung subsir strict crescator 
	// este format doar din elementul sir[i], deci, dp[i] = 1.
	// Apoi, verificam daca putem forma un alt subsir mai lung prin concatenarea elementului sir[i] la un 
	// alt subsir strict crescator determinat anterior.
	// Solutia finala o determinam parcurgand tabloul dp si stabilind valoarea maxima din acesta.
	// Complexitate: O(n^2)
	// Exista o varianta optimizata in O(n log n), bazata pe cautare binara,
	// dar aceasta foloseste o abordare diferita fata de programarea dinamica de mai sus.
	for(int i = 0; i < n; i++) {
		dp[i] = 1;
		elAnterior[i] = -1; // daca elAnterior[i] este -1, atunci i este primul element in subsirul de lungime maxima

		for(int j = 0; j < i; j++) {
			if(sir[j] < sir[i] && dp[j] + 1 > dp[i]) {
				dp[i] = dp[j] + 1;
				elAnterior[i] = j;
			}
		}
	}


	// idxSubsirMax reprezinta indicele la care se afla elementul cu care se termina un subsir strict crescator de lungime maxima
	// nu initializez variabila, fiindca, conform restrictiilor problemei, N >= 1
	int idxSubsirMax;
	// lMax reprezinta lungimea subsirului strict crescator de lungime maxima
	int lMax = 0;

	for(int i = 0; i < n; i++) {
		if(dp[i] > lMax) {
			lMax = dp[i];
			idxSubsirMax = i;
		}
	}

	fout << lMax << "\n";

	// ne folosim de recursivitate pentru a afisa elementele in ordine crescatoare
	afisareSubsir(idxSubsirMax);

	fout << "\n";

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

	return 0;
}