Cod sursa(job #3239160)

Utilizator filipinezulBrain Crash filipinezul Data 2 august 2024 16:58:11
Problema Subsir crescator maximal Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.53 kb
#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;
}