Cod sursa(job #2002086)

Utilizator dan.marculetFII MarculetDan dan.marculet Data 18 iulie 2017 16:30:46
Problema Subsir crescator maximal Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.23 kb
#include <cstdio>
#include <vector>
#include <numeric>
#include <stack>
using namespace std;

#define NAME "scmax"

auto fin = fopen(NAME ".in", "r");
auto fout = fopen(NAME ".out", "w");

int n;
vector<int> v;

// int main() {
//     fscanf(fin, "%d", &n);
//     v.resize(n);
//     for (auto i = 0; i < n; ++i)
//         fscanf(fin, "%d", &v[i]);


// }

// Cautare binara

int main() {
    fscanf(fin, "%d", &n);
    v.resize(n);
    for (auto i = 0; i < n; ++i)
        fscanf(fin, "%d", &v[i]);

    vector<int> best, pre;
    int maxlen;
    best.resize(n + 1);
    pre.resize(n);
    best[1] = 0;
    maxlen = 1;

    for (auto i = 0; i < n; ++i) {
        auto lo = 1;
        auto hi = maxlen;
        while (lo <= hi) {
            auto mid = float(lo + hi) / 2;
            if (v[best[mid]] < v[i])
                lo = mid + 1;
            else
                hi = mid - 1;
        }
        pre[i] = best[lo - 1];
        best[lo] = i;
        if (lo > maxlen)
            maxlen = lo;
    }
    stack<int> s;
    auto idx = best[maxlen];
    for (auto i = maxlen; i > 0; --i) {
        s.push(v[idx]);
        idx = pre[idx];
    }
    fprintf(fout, "%d\n", s.size());
    while (!s.empty()) {
        auto val = s.top();
        s.pop();
        fprintf(fout, "%d ", val);
    }
    return 0;
}

// Programare dinamica

// int main() {
//     fscanf(fin, "%d", &n);
//     v.resize(n);
//     for (auto i = 0; i < n; ++i)
//         fscanf(fin, "%d", &v[i]);
//     vector<int> best, pre;
//     best.resize(n, 1);
//     pre.resize(n, -1);
//     for (auto i = 0; i < n; ++i) {
//         int maxlen = 0;
//         for (auto j = 0; j < i; ++j)
//             if (v[j] < v[i] && best[j] > maxlen) {
//                 maxlen = best[j];
//                 pre[i] = j;
//             }
//         best[i] += maxlen;
//     }
//     int maxleni = 0;
//     for (auto i = 0; i < best.size(); ++i)
//         if (best[maxleni] < best[i])
//             maxleni = i;
//     stack<int> s;
//     while (maxleni != -1) {
//         s.push(v[maxleni]);
//         maxleni = pre[maxleni];
//     }
//     fprintf(fout, "%d\n", s.size());
//     while (!s.empty()) {
//         auto val = s.top();
//         s.pop();
//         fprintf(fout, "%d ", val);
//     }
//     return 0;
// }


// Brute force solution

// int n;
// vector<int> v;
// vector<int> solution;
// vector<int> current;

// void find(int level, int start_i) {
//     auto solution_sum = accumulate(solution.begin(), solution.end(), 0);
//     auto current_sum = accumulate(current.begin(), current.end(), 0);
//     if (current_sum > solution_sum)
//         solution = current;
//     for (auto i = start_i; i < n; ++i) {
//         if (!current.size() || v[i] > current.back()) {
//             current.push_back(v[i]);
//             find(level + 1, i + 1);
//             current.pop_back();
//         }
//     }
// }

// int main() {
//     fscanf(fin, "%d", &n);
//     v.resize(n);
//     for (auto i = 0; i < n; ++i)
//         fscanf(fin, "%d", &v[i]);
//     find(0, 0);
//     for (auto val: solution)
//         printf("%d ", val);
//     printf("\n");
//     return 0;
// }