Pagini recente » Cod sursa (job #989670) | Cod sursa (job #1494590) | Cod sursa (job #2040299) | Borderou de evaluare (job #2414961) | Cod sursa (job #3353210)
// https://www.infoarena.ro/problema/scmax
#include<fstream>
using namespace std;
ifstream fin("scmax.in");
ofstream fout("scmax.out");
int n;
int sir[100000];
// definirea starii (subproblemei):
// dp[i] - este lungimea maxima a subsirului strict crescator care se incheie cu elementul sir[i]
int dp[100000];
// elAnterior reprezinta indicele la care se afla elementul anterior elementului sir[i],
// atunci cand concatenam pe sir[i] la un alt subsir strict crescator.
int elAnterior[100000];
void afisareSubsir(int i) {
if(i >= 0) {
afisareSubsir(elAnterior[i]);
fout << sir[i] << " ";
}
}
int main() {
fin >> n;
for(int i = 0; i < n; i++) {
fin >> sir[i];
}
// Problema o vom rezolva cu programare dinamica astfel:
// Parcurgem sirul de la primul element pana la ultimul element, folosind indicele i.
// La fiecare indice i, consideram, initial, ca cel mai lung subsir strict crescator
// este format doar din elementul sir[i], deci, dp[i] = 1.
// Apoi, verificam daca putem forma un alt subsir mai lung prin concatenarea elementului sir[i] la un
// alt subsir strict crescator determinat anterior.
// Solutia finala o determinam parcurgand tabloul dp si stabilind valoarea maxima din acesta.
// Complexitate: O(n^2)
// Exista o varianta optimizata in O(n log n), bazata pe cautare binara,
// dar aceasta foloseste o abordare diferita fata de programarea dinamica de mai sus.
for(int i = 0; i < n; i++) {
dp[i] = 1;
elAnterior[i] = -1; // daca elAnterior[i] este -1, atunci i este primul element in subsirul de lungime maxima
for(int j = 0; j < i; j++) {
if(sir[j] < sir[i] && dp[j] + 1 > dp[i]) {
dp[i] = dp[j] + 1;
elAnterior[i] = j;
}
}
}
// idxSubsirMax reprezinta indicele la care se afla elementul cu care se termina un subsir strict crescator de lungime maxima
// nu initializez variabila, fiindca, conform restrictiilor problemei, N >= 1
int idxSubsirMax;
// lMax reprezinta lungimea subsirului strict crescator de lungime maxima
int lMax = 0;
for(int i = 0; i < n; i++) {
if(dp[i] > lMax) {
lMax = dp[i];
idxSubsirMax = i;
}
}
fout << lMax << "\n";
// ne folosim de recursivitate pentru a afisa elementele in ordine crescatoare
afisareSubsir(idxSubsirMax);
fout << "\n";
fin.close();
fout.close();
return 0;
}