Cod sursa(job #2124926)

Utilizator loo_k01Luca Silviu Catalin loo_k01 Data 7 februarie 2018 18:42:52
Problema Subsir crescator maximal Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.73 kb
#include <bits/stdc++.h>
using namespace std;
ofstream fout("scmax.out");

const int Nmax = 1E5 + 5;
int a[Nmax];
int dp[Nmax]; /// Lungimea maxima a unui subsir care incepe cu a[i]
int urm[Nmax];/// Vector pentru reconstructia drumului
int n;


void Read()
{
    ifstream fin("scmax.in");
    fin >> n;
    for (int i = 1; i <= n; i++)
        fin >> a[i];
    fin.close();
}

void LIS()
{
    int i, j, M, poz;
    /// Initializare
    dp[n] = 1;
    urm[n] = n + 1;

    for (i = n; i >= 1; --i) /// i = n -> 1  - - - Solutie Minim Lexicografica
    {
        /// Initializare Iar
        poz = n + 1; /// in caz ca se va incepe un nou sir val lui urm[i] va fi n + 1 (oo)
        M = 0;       /// Maximul = 0

        for (j = i + 1; j <= n; j++)        /// Caut un subsir la care a[i] poate fi inceputul... Solutia N^2
            if (a[i] < a[j] && M < dp[j])   /// daca a[i] poate fi inserat in subsirul continuat din a[j] si lg secv va fi maximala
            {
                M = dp[j]; /// actualizez maxim
                poz = j;   /// retin pozitia pentru reconstituirea drumului
            }
        dp[i] = M + 1; /// Lg secv maximala + 1 sau 1 in caz ca sirul este nou
        urm[i] = poz;  /// poz precedenta de unde am luat Maximul sau n + 1 daca este nou
    }
    /// caut Lg maxima si retin capatul unde incepe
    M = 0;
    poz = n + 1;
    for (i = 1; i <= n; i++)
        if (dp[i] > M)
        {
            M = dp[i];
            poz = i;
        }

    fout << M << "\n";
    /// Parcurg pentru reconstructie
    while(poz <= n)
    {
        fout << a[poz] << " ";
        poz = urm[poz];
    }
    fout.close();
}

int main()
{
    Read();
    LIS();
    return 0;
}