Nu aveti permisiuni pentru a descarca fisierul grader_test10.ok
Diferente pentru deque-si-aplicatii intre reviziile #123 si #122
Nu exista diferente intre titluri.
Diferente intre continut:
Voi prezenta mai jos o rafinare a soluţiei în trei paşi.
Prima rezolvare se găseşte uşor, deoarece nu facem decât să urmărim textul: pentru fiecare poziţie $i$ fixată ({$i$} ia valorile $1$, $2$, ..., $N$ succesiv) vom considera toate secvenţele candidate la rezultatul final, adică vom plimba un $j$ între poziţiile $i - Y+ 1$ şi $i - X+ 1$. Pentru un interval $[j, i]$ vom determina $MAX$ şi $MIN$ în $O(log N)$ cu un arbore de intervale, iar dacă diferenţa dintre acestea nu depăşeşte $Z$ vom compara rezultatul cu cel obţinut până în acel moment. Complexitatea finală va fi $O(N * (Y - X) * log N)$.
Prima rezolvare se găseşte uşor, deoarece nu facem decât să urmărim textul: pentru fiecare poziţie $i$ fixată ({$i$} ia valorile $1$, $2$, ..., $N$ succesiv) vom considera toate secvenţele candidate la rezultatul final, adică vom plimba un $j$ între poziţiile $i - Y$ şi $i - X$. Pentru un interval $[j, i]$ vom determina $MAX$ şi $MIN$ în $O(log N)$ cu un arbore de intervale, iar dacă diferenţa dintre acestea nu depăşeşte $Z$ vom compara rezultatul cu cel obţinut până în acel moment. Complexitatea finală va fi $O(N * (Y - X) * log N)$.
Cum se cere secvenţa de lungime maximă, pentru fiecare poziţie $i$ trebuie găsit indicele $j$ cât mai mic cuprins între $i - Y+ 1$ şi $i - X+ 1$ astfel încât secvenţa $[j, i]$ să fie candidată la soluţie. Ce proprietăţi are indicele $j$?
Cum se cere secvenţa de lungime maximă, pentru fiecare poziţie $i$ trebuie găsit indicele $j$ cât mai mic cuprins între $i - Y$ şi $i - X$ astfel încât secvenţa $[j, i]$ să fie candidată la soluţie. Ce proprietăţi are indicele $j$?
* $i - Y+ 1≤ j ≤ i - X+ 1$ şi $MAX - MIN ≤ Z$;
* $i - Y ≤ j ≤ i - X$ şi $MAX - MIN ≤ Z$;
* având $i$-ul fixat, dacă trecem de la $j$ la $j + 1$, maximul poate scădea, iar minimul poate creşte, dar în mod sigur diferenţa lor va rămâne mai mică sau egală cu $Z$; soluţia astfel obţinută este mai scurtă, deci nu îmbunătăţeşte soluţia obţinută anterior.
* dacă trecem de la $i$ la $i + 1$, cel mai mic $j$ găsit la pasul anterior poate ori să nu corespundă celor două restricţii (caz în care îl incrementăm cât timp $j < i-Y+2$ sau $MAX - MIN > Z$), ori să corespundă şi atunci este cel mai mic care să respecte proprietăţile pentru $i + 1$.
* dacă trecem de la $i$ la $i + 1$, cel mai mic $j$ găsit la pasul anterior poate ori să nu corespundă celor două restricţii (caz în care îl incrementăm cât timp $j < i + 1 - Y$ sau $MAX - MIN > Z$), ori să corespundă şi atunci este cel mai mic care să respecte proprietăţile pentru $i + 1$.
Pentru determinarea lui $MAX$, respectiv lui $MIN$ pe fiecare interval $[j, i]$, se poate folosi un arbore de intervale. Complexitatea finală va fi $O(N * log N)$.
// S şirul de numere iniţial şi N lungimea sa // Subalgoritmul push() inserează în deque poziţia p din şirul S în conformitate cu
// funcţiabooleanăfct, o funcţie generică
// funcţia fct, o funcţie generică
Subalgoritmul push(deque, întreg p, funcţia fct) este: cât timp (!deque.empty() şi fct(S[p], S[deque.back()])) execută deque.pop_back();
Sfârşit; // Funcţia query() întoarce numărul din S corespunzător primului indice
// din deque aflat în intervalul de interes[j, i].
// din deque aflat în intervalul de interes (j, i].
Funcţia query(deque, întreg j) este:
cât timp (!deque.empty() şi deque.front() < j) execută
cât timp (!deque.empty() şi deque.front() <= j) execută
deque.pop_front(); return S[deque.front()]; Sfârşit;
Algoritmul este: lg = 0; pentru i = 1, N execută
// funcţia min(a, b) întoarce true dacă a <=b
// funcţia min(a, b) întoarce true dacă a < b
push(min_deq, i, min);
// funcţia max(a, b) întoarce true dacă a >=b
// funcţia max(a, b) întoarce true dacă a > b
push(max_deq, i, max);
cât timp ((j <=i - Y sau query(max_deq, j) - query(min_deq, j) > Z) şi j <=i - X+ 1) execută
cât timp ((j < i - Y sau query(max_deq, j) - query(min_deq, j) > Z) şi j < i - X) execută
j = j + 1; // (j, i] este intervalul candidat la soluţia optimă pentru poziţia i dacă (j <= i - X) şi (query(max_deq, j) - query(min_deq, j) <= Z) atunci