Pagini recente » Monitorul de evaluare | Cod sursa (job #2104761) | Istoria paginii runda/kl/clasament | Cod sursa (job #2407951) | Cod sursa (job #489281)
Cod sursa(job #489281)
#include <stdio.h>
#include <stdlib.h>
// bazat pe: http://en.wikipedia.org/w/index.php?title=Longest_increasing_subsequence&oldid=357958000
int X[100001]; // valoarea celui de-al i-lea numar
int n;
int M[100001]; // M[i] pozitia ultimului element din subsirul cu lungimea i. daca sunt mai multe subsire, se ia cel cu X[M[i]] minim.
// X[M[i]] este un sir nedescrescator. Deoarece daca exista un subsir care se termina cu X[M[i]], atunc exista unul care se termina cu acelasi element
// dar are lungimea cu 1 mai mica. X[M[i-1]] va fi limitat superior de aceasta valoare.
int L;
int P[100001]; // pozitia anterioara in subsir, folosit pentru afisare.
int b_search(int val) { // returneaza j maxim, astfel incat X[M[j]] < val
if (L==0) return 0;
int step, i;
for (step=1;step<L;step<<=1);
for (i=0;step;step>>=1)
if (i+step<L && X[M[i+step+1]]<val)
i+=step;
if (X[M[i+1]]<val) return i+1;
return 0;
}
int main() {
int i, j;
freopen("scmax.in", "r", stdin);
freopen("scmax.out", "w", stdout);
scanf("%d" , &n);
for (i=0;i<n;i++) scanf("%d", &X[i]);
L = 0;
for (i=0;i<n;i++) {
int j = b_search(X[i]);
P[i] = M[j];
if (L==j || X[M[j+1]]>X[i]) { // am gasit o solutie mai buna pentru M[j+1]!
M[j+1] = i;
if (j+1>L) L = j+1;
}
}
i = M[L]; j = 0;
while(1) {
M[j] = X[i];
if (i==0) break;
j++;
i = P[i];
}
printf("%d\n", L);
for (i=L-1;i>=0;i--) printf("%d ", M[i]);
printf("\n");
return 0;
}