Pagini recente » Cod sursa (job #2291540) | Cod sursa (job #1449029) | Cod sursa (job #1258152) | Cod sursa (job #1877261) | Cod sursa (job #2799147)
#include <fstream>
#include <climits>
using namespace std;
const int NMAX = 100000;
int v[1 + NMAX];
int dp[1 + NMAX];
int lastIndex[1 + NMAX];
/*
lastIndex[i] = pozitia pe care se afla valoarea tinuta in dp[i];
*/
int tata[1 + NMAX];
/* Daca v[i] face parte dintr-un subsir crescator, atunci tata[i] tine de fapt un j care inseamna faptul ca v[j] era elementul anterior lui v[i] in subsirul crescator in care se afla v[i]. v[i] se poate afla in mai multe subsiruri crescatoare, dar in asta il tinem pe ala de lungime maxima si care se termina in valoare cat mai mica, adica ce tinem in dp de fapt.
*/
int cautareBinara(int st, int dr, int val)
{
int sol = 0;
while (st <= dr)
{
int mij = (st + dr) / 2;
if (dp[mij] < val)
{
sol = mij;
st = mij + 1;
}
else
{
dr = mij - 1;
}
}
return sol;
}
ifstream in("scmax.in");
ofstream out("scmax.out");
void afisareSolutie(int index)
{
if (tata[index] != 0)
afisareSolutie(tata[index]);
out << v[index] << ' ';
}
int main()
{
int n;
in >> n;
int sol = 0;
for (int i = 1; i <= n; i++)
{
in >> v[i];
dp[i] = INT_MAX;
int poz = cautareBinara(0, i, v[i]);
dp[poz + 1] = v[i];
lastIndex[poz + 1] = i;
tata[i] = lastIndex[poz];
if (poz + 1 > sol)
sol = poz + 1;
}
out << sol << '\n';
afisareSolutie(lastIndex[sol]);
out << '\n';
return 0;
}