Cod sursa(job #1183298)

Utilizator andreeadeacAndreea Ioana Deac andreeadeac Data 8 mai 2014 19:30:51
Problema Subsir crescator maximal Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.38 kb
#include <fstream>
using namespace std;

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

const int N=100000;
int v[N+1], pred[N+1], mic[N+1],n,m;
/*
3 8 5 1 2 4 3 6
"pot forma un subsir de lungime k, care se termina cu v[i]?"
"da, daca exista un subsir de lungime k-1, construit inainte de pasul i, care sa se termine cu ceva mai mic decat v[i]"
as avea nevoie de cea mai mica val cu care se termina un subsir de lungime k - 1
mic[j] = cea mai mica valoare cu care se poate termina un subsir de lungime j
mic = (1, 2, 4)

la pasul i: caut binar in mic cel mai mare j cu propietatea ca mic[j] < v[i] si completez mic[j+1] = v[i]

pentru a reface subsirul, imi fac si un vector pred si in mic retin pozitii:
la pasul i: caut binar in mic cel mai mare j cu propietatea ca v[mic[j]] < v[i] si completez mic[j+1] = i si pred[i] = mic[j]
*/

int caut(int x){
    int pas=1<<16, i=0 ;
    while( pas != 0){
        if(i+pas <= m && v[mic[i+pas]] < x)
            i+=pas;
        pas/=2;
    }
    return i;

}

void lant(int j){
    if(pred[j]!=0)
        lant(pred[j]);
    out<<v[j]<<" ";
}
int main()
{
    int i,j,k;
    in>>n;
    for(i=1;i<=n;i++)
        in>>v[i];
    mic[++m]=1;
    for(i=2;i<=n;i++){
        j=caut(v[i]);
        if(j == m) m++;
        mic[j+1]=i;
        pred[i]=mic[j];
    }
    out<<m<<"\n";
    lant(mic[m]);
    return 0;
}