Pagini recente » Cod sursa (job #2512304) | Cod sursa (job #159388) | Cod sursa (job #1364523) | Cod sursa (job #275687) | Cod sursa (job #3239160)
#include <bits/stdc++.h>
using namespace std;
/**
* @brief Subsequence crescator maximal
* 24 12 15 15 19 ==> 12 15 19
*/
class Task { // T = O(n), S = O(1)
public:
void solve() {
read_input();
get_result();
print_output();
}
private:
int32_t n;
int32_t sol;
vector<int32_t> v;
vector<int32_t> dp;
vector<int32_t> prec; // pozitiile precedente ale subsirului
vector<int32_t> scmax; // subsirul cu lungime maxima crescator
void read_input() {
ifstream fin("scmax.in");
fin >> n;
v.resize(n + 1);
dp.resize(n + 1);
prec.resize(n + 1);
for (int i = 1; i <= n; i++) {
fin >> v[i];
}
fin.close();
}
void build_scmax(int pos) {
for (int i = 1; i <= sol; ++i) {
// v[pos] este ultimul element pe care il stiu din SCMAX
scmax.push_back(v[pos]);
// inainte de el era v[prec[pos]] (..., v[ prec[pos] ], v[ pos ])
pos = prec[pos];
}
reverse(scmax.begin(), scmax.end()); // oglindire vector solutie
}
void get_result() {
// caz de baza
dp[1] = 1; // [ v[1] ] este singurul subsir (cresc) cu 1 la final
prec[1] = 0; // nu are precedent
// caz general
for (int i = 2; i <= n; ++i) {
dp[i] = 1; // [ v[i] ] - este un subsir (cresc) care se termină pe i
for (int j = 1; j < i; ++j) {
if (v[j] < v[i]) {
// din (..., v[j]) pot obține (..., v[j], v[i])
// (caz în care prec[i] = j)
// voi alege j-ul curent, când alegerea îmi găsește o soluție mai bună decât ce am deja
if (dp[j] + 1 > dp[i]) {
dp[i] = dp[j] + 1;
prec[i]= j;
}
}
}
}
sol = dp[1];
int32_t pos = 1;
for (int i = 2; i <= n; ++i) {
if (dp[i] > sol) {
sol = dp[i];
pos = i;
}
}
build_scmax(pos);
}
void print_output() {
ofstream fout("scmax.out");
fout << sol << "\n";
for (int i = 0; i < sol; ++i) {
fout << scmax[i] << " ";
}
fout << "\n";
fout.close();
}
};
int main() {
auto* task = new (nothrow) Task();
if (!task) {
std::cerr << "new failed\n";
return -1;
}
task->solve();
delete task;
return 0;
}