Pagini recente » Cod sursa (job #872422) | Borderou de evaluare (job #1004805) | Borderou de evaluare (job #2247334) | Cod sursa (job #931327) | Cod sursa (job #2124926)
#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;
}