Pagini recente » Cod sursa (job #2731659) | Cod sursa (job #2142267) | Cod sursa (job #395804) | Cod sursa (job #2035615) | Cod sursa (job #3350939)
// https://www.infoarena.ro/problema/scmax
#include<fstream>
using namespace std;
ifstream fin("scmax.in");
ofstream fout("scmax.out");
int n;
int sir[100001];
// dp[i] memoreaza lungima maxima a subsirului crescator ce se incheie cu elementul i
int dp[100001];
// posMax reprezinta pozitia ultimului element care face parte din subsirul crescator de lungime maxima
// initial, posMax ia valoarea 0, adica cel mai lung subsir crescator este format doar din primul element al sirului
// (memorarea subsirului incepe de la pozitia 0)
// elementAnterior[i] reprezinta indexul in vectorul sir al elementului ce precede elementul sir[i] in subsirul crescator
// daca elementAnterior[i] == -1, atunci sir[i] este primul element al subsirului crescator (niciun element nu ii precede)
int elementAnterior[100001];
int posMax = 0;
void afisareSubsir(int index) {
if(index < 0) {
return; // daca am ajuns la un index negativ (-1), inseamna ca am afisat deja primul element al subsirului
}
afisareSubsir(elementAnterior[index]);
fout << sir[index] << " ";
}
int main() {
fin >> n;
for(int i = 0; i < n; i++) {
fin >> sir[i];
}
// primul element face parte dintr-un subsir crescator de lungime 1 (nu are niciun alt element in fata lui),
// deci vom rula algoritmul de programare dinamica incepand cu al doilea element
dp[0] = 1;
for(int i = 1; i < n; i++) {
// initial, lungimea subsirului ce se termina cu elementul sir[i] este 1 (subsirul care are doar pe sir[i] ca element),
// iar niciun element nu ii precede in subsirul crescator
dp[i] = 1;
elementAnterior[i] = -1;
// verificam in stanga elementului daca gasim elemente mai mici decat el
for(int j = 0; j < i; j++) {
if(sir[j] < sir[i]) {
// daca am gasit un element mai mic decat el, atunci il putem adauga in subsirul crescator
// iar lungima subsirului ce se termina cu sir[i] va fi egala cu lungimea subsirului ce se termina cu sir[j] + 1
// doar ca putem gasi mai multe elemente mai mici decat sir[i], iar atunci vom alege elementul care ne ofera o lungime cat mai mare
if(dp[i] < dp[j] + 1){
dp[i] = dp[j] + 1;
elementAnterior[i] = j;
}
}
}
// actualizam pozitia la care am gasit lugima maxima
if(dp[posMax] < dp[i]) {
posMax = i;
}
}
fout << dp[posMax] << endl;
// ne folosim de recursivitate pentru a afisa in ordine crescatoare subsirul, pornind de la indexul ultimului element pana la indexul primului element din subsir
afisareSubsir(posMax);
fout << endl;
fin.close();
fout.close();
return 0;
}