Pagini recente » Cod sursa (job #628827) | Cod sursa (job #455727) | Cod sursa (job #3226490) | Cod sursa (job #755848) | Cod sursa (job #1254592)
#include <cstdio>
#include <iostream>
#include <fstream>
#include <vector>
#include <list>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <sstream>
#include <iomanip>
#include <cmath>
#include <cstdlib>
#include <ctype.h>
#include <cstring>
#include <string>
#include <ctime>
#include <cassert>
#include <utility>
using namespace std;
#define LIM 100005
int dp[LIM], A[4 * LIM + 10], maxim, pos, val, inceput, sfarsit;
// idee ce utilizeaza DP + Arb de Intervale
// ideea acestui program este ca se calculeaza cu
// programare dinamica: lungimea celui mai lung subsir care se termina in i si care respecta ca e strict crescator
// doar ca acum se priveste inapoi si atunci tranzitiile sunt:
// dp[i] = max(dp[j] | j < i && dp[i] > dp[j]) + 1;
// pentru a calcula acel maxim in timp mai mic de o(n) putem sa o facem utilizand arborii de intervale
void updateARB(int nod, int st, int dr) {
if(st == dr) { // am ajuns la o frunza - am ajuns pe pozitia care vreau sa updatez
A[nod] = val;
return;
}
int m = (st + dr) / 2;
if(pos <= m)
updateARB(2 * nod, st, m);
else
updateARB(2 * nod + 1, m + 1, dr);
A[nod] = max(A[2 * nod], A[2 * nod + 1]);
}
void queryARB(int nod, int st, int dr) {
if(inceput <= st && dr <= sfarsit) {
if(maxim < A[nod])
maxim = A[nod];
return;
}
int m = (st + dr) / 2;
if(m >= inceput)
queryARB(2 * nod, st, m);
if(m < sfarsit)
queryARB(2 * nod + 1, m + 1, dr);
}
int main() {
freopen("scmax.in", "r", stdin);
freopen("scmax.out","w", stdout);
int n, a[LIM];
cin >> n;
for(int i = 1; i <= n; i++) {
cin >> a[i];
}
// initializare dp
for(int i = 0; i <= n; i++) {
dp[i] = 1;
}
inceput = 1;
sfarsit = n;
// problema cere lg celui mai lung subsir (nu neaparat cel care se termina in n) -> caut maximul dintre toate cele n calculate
int mTotal = -1;
// dp[i] = "lungimea celui mai lung subsir care se termina in i"
for(int i = 1; i <= n; i++) {
maxim = -1;
for(int j = 1; j < i; j++) {
if(a[j] < a[i]) {
pos = j;
val = dp[j];
updateARB(1, 1, n);
}
}
queryARB(1, 1, n);
dp[i] = maxim + 1;
}
int mx = -1, pos = -1;
for(int i = 1; i <= n; i++) {
if(mx < dp[i]) {
mx = dp[i];
pos = i;
}
}
cout << mx << "\n";
vector<int> v;
for(int i = pos; i > 0 && mx > 0; i--) {
if(dp[i] == mx) {
v.push_back(a[i]);
mx--;
}
}
reverse(v.begin(), v.end());
int sz = v.size();
for(int i = 0; i < sz - 1; i++) {
cout << v[i] << " ";
}
if(sz - 1 >= 0)
cout << v[sz - 1] << "\n";
return 0;
}