De ce contează?
La un concurs de sărituri, după fiecare concurent se afișează „cel mai bun rezultat de până acum”. Nu se recalculează tot clasamentul — se compară doar noua săritură cu recordul curent. Exact asta face maximul pe prefix.
Ce este maximul pe prefix
Un prefix al vectorului sunt primele i elemente. Maximul pe prefix pmax[i] e cel mai mare element dintre primele i:
pmax[i] = max(v[1], v[2], ..., v[i]).
La fel definim minimul pe prefix pmin[i]. Le construiești dintr-o singură parcurgere, comparând fiecare element nou cu cel mai bun de până atunci.
Recurența e simplă: cel mai bun de până la i e fie cel mai bun de până la i-1, fie chiar v[i]. Deci pmax[i] = max(pmax[i-1], v[i]).
Pas cu pas pe numere
Fie v = {4, 2, 7, 3, 9, 5} (indici 1..6).
| v | 4 | 2 | 7 | 3 | 9 | 5 |
1 | 2 | 3 | 4 | 5 | 6 |
Construim pmax comparând fiecare element cu recordul curent:
| pmax | 4 | 4 | 7 | 7 | 9 | 9 |
1 | 2 | 3 | 4 | 5 | 6 |
Observă cum pmax nu scade niciodată — odată ce ai văzut un record, el rămâne până apare unul mai mare.
Implementare C++
#include <iostream>
using namespace std;
int main() {
int v[] = {0, 4, 2, 7, 3, 9, 5}; // v[0] nefolosit
int n = 6;
int pmax[100], pmin[100];
pmax[1] = pmin[1] = v[1];
for (int i = 2; i <= n; i++) {
pmax[i] = max(pmax[i - 1], v[i]); // record maxim de pana aici
pmin[i] = min(pmin[i - 1], v[i]); // record minim de pana aici
}
for (int i = 1; i <= n; i++) cout << pmax[i] << " ";
cout << "\n"; // 4 4 7 7 9 9
return 0;
}La ce folosește: maximul „în afară de poziția i”
Combinând prefixul cu sufixul (vezi lecția următoare) poți răspunde la întrebări de tip „care e maximul tuturor elementelor, ignorându-l pe v[i]?”:
maxFaraI = max(pmax[i-1], smax[i+1]).
Asta e util, de pildă, când vrei pentru fiecare poziție produsul/maximul celorlalte elemente, fără bucle imbricate.
Complexitate
| Etapă | Timp | Spațiu |
|---|---|---|
Construire pmax/pmin | O(n) | O(n) |
| Fiecare interogare „prefix” | O(1) | — |
Vizualizare
Urmărește cum, la fiecare poziție, recordul de până atunci se compară cu elementul curent și pmax urcă în trepte, fără să scadă vreodată:
Greșeli frecvente de concurs:
- Inițializare greșită. Dacă pornești
pmaxcu0și vectorul are numere negative, primești un maxim fals. Inițializează cuv[1], nu cu0sau cu o constantă arbitrară. - Confuzi prefix cu maximul global.
pmax[i]e maximul până lai, nu al întregului vector. Maximul global epmax[n]. - Off-by-one la combinarea cu sufixul. Pentru „în afară de
i” foloseștipmax[i-1]șismax[i+1]— nupmax[i], care l-ar include pev[i]. - Margini neglijate. La
i = 1nu existăpmax[0]util; lai = nnu există sufix după el. Tratează capetele separat.
Recapitulare
pmax[i]= cel mai bun element dintre primelei, construit cumax(pmax[i-1], v[i]).- Maximul pe prefix nu scade niciodată; maximul global e
pmax[n]. - Combinat cu sufixul, răspunde în O(1) la „maximul în afară de poziția
i”.