Cod sursa(job #2963566)

Utilizator Bogdan345Marius Mihalache Bogdan345 Data 11 ianuarie 2023 15:22:39
Problema Subsir crescator maximal Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.88 kb
/*
//Metoda I(n^2)-repet pentru fiecare pozitie i
//ma uit in urma sa si caut subsirul cu de lungime maxima
//cu capatul nr[i]
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
vector<int>nr,dp,inainte;
// dp reprezinta cel mai mare
//subsir cu capatul nr[i]
//verific pentru fiecare pozitie care este
//cel mai pun subsir in care imi pot adauga numarul
int main()
{
  int n;
  cin>>n;
  nr.resize(n+1);
  dp.resize(n+1);
  inainte.resize(n+1);
  nr[0]=0;
  dp[0]=0;
  for(int i=1;i<=n;i++){
    cin>>nr[i];
  }
  for(int i=1;i<=n;i++){
    for(int j=0;j<i;j++){
        if(nr[j]<nr[i]){//cauta numere mai mici ca mine
//ca sa fiu sigur ca si subsirurile lor au elemente mai mici
//ca mine si ca am o ordine strict crescatoare
            if(dp[j]+1>dp[i]){//actualizez mereu stare dp-ului
//adaugandu-ma si pe mine in acel subsir si verific daca am gasit
//un subsir care ma contine pe mine si este de lungime mai mare
//daca da ,imi actualizez starea
                dp[i]=dp[j]+1;
                inainte[i]=j;
            }
        }
    }
  }
  //imi caut pozitia subsirului de lungime maxima
  //imi retin un vector de care ma voi folosi
  //ulterior, pentru a stii de unde vin
  //adaug elementele intr-un vector de int
  //si dupa ii dau reverse
  int ultimaPozitie=0;
  for(int i=1;i<=n;i++){
    if(dp[i]>dp[ultimaPozitie]){
        ultimaPozitie=i;
    }
  }
    vector<int>raspuns;
  while(ultimaPozitie!=0){
    raspuns.push_back(nr[ultimaPozitie]);
    ultimaPozitie=inainte[ultimaPozitie];
  }
  reverse(raspuns.begin(),raspuns.end());
  cout<<raspuns.size()<<'\n';
  for(auto&x:raspuns){
    cout<<x<<" ";
  }
    return 0;
}
*/
#include <fstream>
#include <vector>
#include <climits>
#include <algorithm>
using namespace std;
int n;
vector<int>dp,nr;
//in dp retin lungimea maxima
//a unui subisr de lungime i,al carui
//capat este cel mai mic nr
vector<int>inainte;
const int inf=INT_MAX;
ifstream cin("scmax.in");
ofstream cout("scmax.out");
int cautBin(int i){
    int raspuns=0;
    int st=0;
    int dr=i-1;
    while(st<=dr){
    int mij=(st+dr)/2;
    if(nr[i]>nr[dp[mij]]){
        raspuns=mij;
        st=mij+1;
    }
    else{
       dr=mij-1;
    }
    }
    return raspuns;
}
int main(){
    cin>>n;
    nr.resize(n+2);
    dp.resize(n+2);
    inainte.resize(n+2);
    for(int i=1;i<=n;i++){
        cin>>nr[i];
        dp[i]=n+1;
    }
    int MAX=-inf;
    nr[n+1]=inf;
    for(int i=1;i<=n;i++){
        int poz=cautBin(i);
        dp[poz+1]=i;
        inainte[i]=dp[poz];
        MAX=max(MAX,poz+1);
    }
    cout<<MAX<<'\n';
    int acum=dp[MAX];
    vector<int>raspuns;
    while(acum){
        raspuns.push_back(nr[acum]);
        acum=inainte[acum];
    }
    reverse(raspuns.begin(),raspuns.end());
    for(auto&x:raspuns){
        cout<<x<<" ";
    }
}