Pagini recente » Cod sursa (job #2781682) | Cod sursa (job #2231627) | Cod sursa (job #2409138) | Cod sursa (job #1869350) | Cod sursa (job #3277021)
// 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;
}