Cod sursa(job #3277021)

Utilizator maxtraAlex Deonise maxtra Data 15 februarie 2025 11:19:54
Problema Subsir crescator maximal Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.57 kb
// LIS - longest increasing sequence
#include <fstream>
#define DIM 100010
using namespace std;
int v[DIM];
int t[DIM]; // pastreaza pozitia elementului precendent din subsirul crescator (necesar constructiei secventei)
int d[DIM]; // retine lungimea celui mai lung subsir crescator care se termina la pozitia i

int n, sol, p, u;

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

void resconstruct_LIS(int u) {
	if (u != 0) {
		resconstruct_LIS(t[u]);
		fout << v[u] << " ";
	}
}

/*
se parcurge fiecare element v[i], iar pentru fiecare dintre cele anterioare, v[j] (j < i), se verifica
daca v[j] < v[i] si daca lungimea d[j] este maxima

actualizez d[i] = 1 + max
si se retine pozitia precendenta in t[i]

determin lungimea maxima si pozitia ultimelei valori din LIS (sol si u)

resconstructia LIS: se parcurge t[i] recursiv pentru a resconstrui subsirul ce se va afisa

O(N^2)

varianta mai eficienta: binary tree index, segement tree reducand la O(N * logN)
*/
int main (void) {
	fin >> n;
	for (int i = 1; i <= n; i++)
		fin >> v[i];
		
	d[1] = 1; // primul element are LIS de lungime 1
	for (int i = 2; i <= n; i++) {
		int maxim = 0, p = 0;
		
		// caut cel mai lung subsir crescator care se termina inainte de i
		for (int j = 1; j < i; j++)
			if (v[j] < v[i] && d[j] > maxim) {
				maxim = d[j];
				p = j;
			}
			
		d[i] = maxim + 1;
		
		t[i] = (d[i] != 1) ? p : 0; // salvez predecesorul sau 0 daca este primul din LIS
		
		// actualizez solutia daca LIS la i este mai lung 
		if (d[i] > sol) {
			sol = d[i];
			u = i;
		}
	}
	
	fout << sol << "\n";
	resconstruct_LIS(u);
	
	return 0;
}