Cod sursa(job #2244064)

Utilizator cosmin.pascaruPascaru Cosmin cosmin.pascaru Data 22 septembrie 2018 00:05:23
Problema Subsir crescator maximal Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.09 kb
#include <stdio.h>
#include <iostream>
#include <fstream>
#include <vector>
#include <array>
#include <algorithm>
#include <vector>
#include <stack>
#include <assert.h>
   
using LL = long long;
using ULL = int long long;
   
const std::string _problemName = "scmax";
   
namespace std {
    std::ifstream fin(_problemName + ".in"); 
    std::ofstream fout(_problemName + ".out"); 
}

#define USE_FILES

#ifdef USE_FILES
    #define cin fin
    #define cout fout
#endif

int computeBestStateIdx(const std::vector<int>& state, const std::vector<int>& v, int currIdx) {
    auto it = std::lower_bound(state.begin(), state.end(), currIdx, [&v](int leftIdx, int rightIdx) { return v[leftIdx] < v[rightIdx]; } );
    return std::distance(state.begin(), it);
}

std::vector<int> computeLongestIncreasingSubsequence(const std::vector<int>& v) {
    // std::vector<int> best(v.size());
    std::vector<int> prev(v.size());
    std::vector<int> state;
 
    for (int currIdx = 0; currIdx < v.size(); ++currIdx) {
        int bestStateIdx = computeBestStateIdx(state, v, currIdx);
 
        if (bestStateIdx >= state.size()) {
            state.push_back(currIdx);
        }
        else {
            state[bestStateIdx] = currIdx;
        }
 
        prev[currIdx] = bestStateIdx ? state[bestStateIdx - 1] : -1;        
    }

    // for (auto i : state) {
    //     std::cout << i << ' ';
    // }
    // std::cout << '\n';

    // for (auto i : prev) {
    //     std::cout << i << ' ';
    // }
    // std::cout << '\n';

    std::vector<int> result(state.size());
    
    int currIdx = state.back();
    for (int resultIdx = result.size() - 1; resultIdx >= 0; --resultIdx) {
        result[resultIdx] = v[currIdx];
        currIdx = prev[currIdx];
    }

    return result;
}
 
int main() {
 
    int n;
    std::cin >> n;
 
    std::vector<int> v(n);
 
    for (int idx = 0; idx < n; ++idx) {
        std::cin >> v[idx];
    }
 
    std::vector<int> lis = computeLongestIncreasingSubsequence(v);
 
    std::cout << lis.size() << '\n';
    for (auto i : lis) {
        std::cout << i << ' ';
    }
    std::cout << '\n';
 
 
    return 0;
}