Cod sursa(job #1228638)

Utilizator MaarcellKurt Godel Maarcell Data 14 septembrie 2014 20:50:44
Problema Secv Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.89 kb
#include <fstream>
#include <algorithm>
#include <iostream>
#define INF (1<<20)
#define prim 10000007
using namespace std;

struct nod{
    int val,l,pos;
    nod *next;
};

int N,a[5050],aux[5050],K,b[5050],dp[5050],posg; nod *table[prim+20];

int srch(int x){
    int ind=x%prim;

    for (nod *p=table[ind]; p!=NULL; p=p->next)
        if (p->val==x){
            posg=p->pos;
            return p->l;
        }

    return INF;
}

void update(int x, int v, int pos){
    int ind=x%prim;

    for (nod *p=table[ind]; p!=NULL; p=p->next)
        if (p->val==x){
            p->l=v;
            p->pos=pos;
            return;
        }

    nod *aux=new nod;
    aux->val=x;
    aux->l=v;
    aux->pos=pos;
    aux->next=table[ind];
    table[ind]=aux;
}

int find_prev(int val){
    int l=1,r=K,mid;

    while (l<=r){
        mid=(l+r)/2;
        if (b[mid]>val)
            r=mid-1;
        else if (b[mid]<val)
            l=mid+1;
        else
            break;
    }

    return (mid-1);
}

int main(){
    ifstream in("secv.in");
    ofstream out("secv.out");
    in >> N;

    int i,pr,len;
    for (i=1; i<=N; i++){
        in >> a[i];
        aux[i]=a[i];
    }

    sort(aux+1,aux+N+1);

    b[0]=-1;
    for (i=1; i<=N; i++)
        if (aux[i]!=b[K])
            b[++K]=aux[i];

    for (i=1; i<=N; i++){
        pr=find_prev(a[i]);
        if (!pr){
            dp[i]=1;
            update(a[i],dp[i],i);
            continue;
        }

        len=srch(b[pr]);
        if (len==INF){
            dp[i]=INF;
            continue;
        }

        dp[i]=len+(i-posg);
        update(a[i],dp[i],i);
    }

    int MIN=(1<<30);
    for (i=1; i<=N; i++)
        if (a[i]==b[K])
            MIN=min(MIN,dp[i]);

    if (MIN==INF)
        out << -1;
    else
        out << MIN;

    out <<"\n";
    return 0;
}