Cod sursa(job #489281)

Utilizator purdea.andreiPurdea Andrei purdea.andrei Data 2 octombrie 2010 10:27:38
Problema Subsir crescator maximal Scor 100
Compilator c Status done
Runda Arhiva educationala Marime 1.54 kb
#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;
}