Cod sursa(job #794549)

Utilizator vendettaSalajan Razvan vendetta Data 6 octombrie 2012 15:12:27
Problema Subsir crescator maximal Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.31 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#include <set>
#include <queue>
#include <deque>

using namespace std;

ifstream f("scmax.in");
ofstream g("scmax.out");

#define nmax 100005
#define ll long long

int n, a[nmax], dp[nmax], Poz[nmax];

void citeste(){

	f >> n;
	for(int i=1; i<=n; ++i) f >> a[i];

}

void cauta(int val, int i){

    int st = 0;
    int dr = dp[0] + 1;

    while(dr - st > 1){
        int mij = (st + dr) / 2;
        if (dp[mij] >= val){
            dr = mij;
        }else st = mij;
    }

    if (dr == dp[0] + 1){//daca trebuie adaugat elementul
        dp[0]++;
        dp[ dp[0] ] = val;
        Poz[ i ] = dp[0];
    }else {
        dp[ dr ] = val;
        Poz[ i ] = dr;
    }

}

void fa_drum(int L, int i){

    for(; Poz[i] != L; --i);
    if (L > 1) fa_drum(L-1, i);

    g << a[i] << " ";

}

void rezolva(){

    //ideea ar fi cam asa : fac un dp[i] = x, unde x e cel mai mic element posibil al unui subsir crescator maximal de lungime i
    //si mai tin minte pe ce pozitie am pus al i-lea element din a[] in dp[]

    for(int i=1; i<=n; ++i){
        cauta(a[i], i);
    }

    g << dp[0] << "\n";
    fa_drum(dp[0], n);
}

int main(){

    citeste();
    rezolva();

    f.close();
    g.close();

    return 0;

}