Cod sursa(job #2491500)

Utilizator AndreiD31Dragan Andrei AndreiD31 Data 12 noiembrie 2019 18:00:33
Problema Subsir 2 Scor 73
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.53 kb
#include <bits/stdc++.h>

using namespace std;

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

int n,i,minim,minim1,minim2,min_sol,elem_anterior,poz,lungime,maxi,j,ok,indice,maxim,sol[5010],l[5010],v[5010];

int main()
{
    f>>n;
    for(i=1;i<=n;i++)
    {
        f>>v[i];
    }

    l[n]=1;
    for(i=n-1;i>=1;i--)
    {
        minim1=INT_MAX;
        minim2=INT_MAX;

        for(j=i+1;j<=n;j++)
        {
            if(v[j]>=v[i] && v[j]<minim1) // adica daca este mai mare decat v[i], dar este cel mai mic de pana acum. daca nu este cel mai mic de pana acum, inseamna ca mai exista un numar intermediar intre v[i] si v[j] => nu se formeaza subsir crescator maximal
            {
                if(l[j]<minim2) minim2=l[j];
                minim1=v[j]; // lui minim1 ii dau update oricum, pentru ca el influenteaza elementele viitoare indiferent de minim2
            }
        }

        if(minim2==INT_MAX)l[i]=1;
        else l[i]=minim2+1;
    }


    minim=INT_MAX;
    min_sol=INT_MAX;
    for(i=1;i<=n;i++)
    {
        // daca v[i] este cel mai mic de pana acum, inseamna ca este capat de sir maximal, deci ii compar l[i] cu minimul meu
        // daca v[i] nu este cel mai mic de pana acum, inseamna ca acesta este doar un element intermediar al unui sir maximal, existand un v[k] mai in spate (k<i) astfel incat v[k]<v[i];
        if(v[i]<minim)
        {
            minim=v[i];
            min_sol=min(min_sol,l[i]);
        }
    }

    g<<min_sol<<'\n';

    poz=0; // pozitia elementului anterior
    elem_anterior=INT_MIN; // initial, la pasul 0 nu exista un element anterior, care sa il margineze pe cel de pe pozitia 1
    for(lungime=min_sol;lungime>=1;lungime--)
    {
        // cautam cel mai mic element ce indeplineste conditia atfel incat l[i]-ul lui = lungime;
        // evident cautam de la poz+1 incolo, pentru ca altfel nu ar avea sens
        // si de asemenea cautam un element care sa fie mai mare decat elementul ales la pasul anterior
        minim=INT_MAX;
        for(i=poz+1;i<=n;i++)
        {
            if(v[i]<minim && l[i]==lungime && v[i]>=elem_anterior)
            {
                minim=v[i];
                poz=i;
            }
          //  else if(v[i]<minim && v[i]>=elem_anterior)minim=v[i]; // trebuie oricum sa dau update la minim, pentru ca daca sunt la un pas j si exista intre elem_anterior si v[j] un alt element intre, atunci clar nu e buna solutia
        }

        g<<poz<<" ";
        elem_anterior=v[poz];
    }


    return 0;
}