Pagini recente » Cod sursa (job #2900640) | Cod sursa (job #2285845) | Cod sursa (job #795884) | Cod sursa (job #1122064) | Cod sursa (job #2800946)
#include <fstream>
#include <vector>
#include <limits>
#include <algorithm>
#include <cassert>
using namespace std;
int binarySearch(const vector <int>& dp, const int& value) {
// https://en.cppreference.com/w/cpp/algorithm/lower_bound
return distance(dp.begin(), lower_bound(dp.begin(), dp.end(), value)) - 1;
}
int main(){
ifstream cin ("scmax.in");
ofstream cout ("scmax.out");
int n;
cin >> n;
vector <int> values(n);
for(int i = 0; i < n; ++ i){
cin >> values[i];
}
vector <int> dp(n + 1, numeric_limits<int>::max());
dp[0] = 0;
// dp[i] = cea mai mica valoare in care se poate termina
// o secventa de lungime i
// dp[j][i] = cea mai mica valoare in care se poate termina
// o secventa de lungime i, dupa ce am procesat primele
// j elemente
// mereu dp[j][i] depinde de dp[j-1][valoare] cu valoare iterata
// dp[1][i=1] = 24; // infoarena exemplu dp[1] = 24
// dp[2][i=1] = 12 dp[1] = 12 // suprascrie 24
// dp[3][i=2] = 15 dp[2] = 15
// dp[4][i=2] = 15 dp[2] = 15
vector <int> lengthToOriginalPosition(n + 1);
lengthToOriginalPosition[0] = -1;
// Cand suntem la o lungime L, practic noi stim care este ultima valoare V
// in care un subsir crescator maximal de lungime L se termina.
// Pentru V noi stim si pozitia pe care aceasta se afla in vectorul initial.
// Acum avem nevoie de un vector care sa ne tina pentru o lungime L pozitia
// din vectorul values al valorii corespunzatoare respectivului subsir
// crescator maximal.
vector <int> originalPositionToPreviousPosition(n + 1, -1);
// Sa presupunem ca avem un subsir crescator maximal de lungime L care se
// termina intr-o valoare V. Pentru acea valoare V cunoastem care este pozitia
// sa in vectorul original (i.e. lengthToOriginalPosition[L]) si acum dorim
// sa cream o relatie intre pozitia valorii V si pozitia valorii Q, unde Q este
// valoare de dinainte de V in subsirul crescator maximal despre care discutam.
pair<int, int> best = {0, 0};
// .first este length
// .second este pozitia ultimului pentru lungimea .first
for (int i = 0; i < n; i ++) { /// schimba modul cum iteram
// place your code
// elem will be placed on pos + 1
int k = binarySearch(dp, values[i]);
dp[k + 1] = values[i];
originalPositionToPreviousPosition[i] = lengthToOriginalPosition[k];
lengthToOriginalPosition[k + 1] = i;
best = max(best, {k + 1, i});
}
cout << best.first << "\n";
// output the sequence!
auto outputSequence = [&](auto&& self, int position) -> void {
if (position == -1) {
return;
}
self(self, originalPositionToPreviousPosition[position]);
cout << values[position] << ' ';
};
outputSequence(outputSequence, best.second);
return 0;
}