InfoBook.ro ← Harta anului
Modul 12 · Metoda Greedy
Modul 12 · Conținut 2.3 · ★ BAC

Lacom, dar cu cap

Casierul care-ți dă restul nu calculează toate combinațiile posibile — ia mereu cea mai mare bancnotă care încape. Alegere local optimă, la fiecare pas, fără să se mai întoarcă. Asta e Greedy: rapidă, elegantă… și uneori înșelătoare.

🎯 Obiectiv 1Înțelegi principiul: la fiecare pas, alegerea cea mai bună ACUM — și nu revii asupra ei.
🎯 Obiectiv 2Aplici Greedy pe clasicele de BAC: restul, coada la ghișeu, spectacolele, sălile și rucsacul.
🎯 Obiectiv 3Recunoști când Greedy DĂ GREȘ — lecția exemplu–contraexemplu.
1

Ideea: alege ce e bun ACUM

Multe probleme cer un optim — cel mai mult, cel mai puțin, cel mai scurt. Greedy le atacă mergând înainte și luând, la fiecare pas, cea mai bună alegere de moment.

Exemplu-far: submulțimea de sumă maximă

Dintr-o mulțime de numere întregi, alege o submulțime cu suma cât mai mare. Pe care le iei?

criteriul lacom: ia fiecare număr STRICT pozitiv 👆

🐌 Forța brută

Încerci TOATE submulțimile și o reții pe cea cu suma maximă. Pentru n numere sunt 2ⁿ submulțimi → O(2ⁿ). La n = 40 deja e imposibil în timp rezonabil.

⚡ Greedy

O singură parcurgere: iei tot ce e pozitiv, ignori restul → O(n). Și e ușor de justificat: orice pozitiv adăugat crește suma, orice negativ ar micșora-o.

Rețeta generală a oricărui Greedy: ① uneori o prelucrare a datelor — de obicei o sortare; ② parcurgi elementele pe rând; ③ adaugi în soluție doar cele care trec criteriul de selecție. Toată dificultatea e să găsești criteriul corect — și să poți justifica de ce funcționează.
2

Casierul lacom — problema restului

Bancnote de 50, 10, 5 și 1 leu. Strategia: mereu cea mai mare care încape. Tastează un rest:

rest =
apasă „Dă restul" și privește bancnotele apărând una câte una 👆
1int b[] = {50, 10, 5, 1}; // SORTATE descrescător!
2for (int i = 0; i < 4; i++)
3 while (rest >= b[i]) {
4 cout << b[i] << " "; // alegerea lacomă
5 rest -= b[i]; // și nu ne mai întoarcem
6 }
Anatomia oricărui Greedy: ① ORDONEZI candidații după un criteriu (aici: valoarea, descrescător) · ② parcurgi și ALEGI tot ce „încape" · ③ nu revii NICIODATĂ asupra unei alegeri. Fără stivă de apeluri, fără jumătăți — doar o parcurgere.
3

Coada la ghișeu — timp mediu de așteptare

La un ghișeu stau n persoane, fiecare cu un timp de servire. Fiecare așteaptă până sunt servite toate din fața ei. În ce ordine le așezăm ca media timpilor de așteptare să fie minimă?

Timpii de servire: 7, 6, 3, 10, 6, 3. Timpul de așteptare al fiecărei persoane = suma timpilor de servire ale celor din fața ei + al ei.

De ce crescător? Timpul de servire al unei persoane se adaugă la așteptarea TUTUROR celor de după ea. Deci pui persoanele rapide în față: ele „costă" puțină așteptare pentru mulți, iar cele lente ajung la coadă, unde întârzie pe cât mai puțini. Criteriul lacom: sortare crescătoare după timpul de servire.
Atenție la implementare: soluția e o REAȘEZARE a persoanelor, nu doar a timpilor — reține perechi (id_persoană, timp) într-o structură și sortează-le după timp. Complexitate: O(n·log n) (sortarea).
4

Problema spectacolelor — o singură scenă

Mai multe spectacole, o singură scenă. Vrem CÂT MAI MULTE, fără suprapuneri. Criteriul lacom câștigător: cel care se TERMINĂ primul.

spectacolele sunt deja sortate după ora de FINAL — apasă Pas 👆

Trei criterii candidate — unul singur e corect

Criteriu lacomVerdictDe ce
după durată (cel mai scurt întâi)✗ greșitun spectacol scurt la mijloc poate bloca două lungi care NU se suprapun între ele
după ora de început✗ greșitunul care începe devreme, dar ține mult, îți fură toată scena
după ora de final✓ corectcine termină primul eliberează scena cel mai devreme → loc maxim pentru rest
Alegerea criteriului e TOATĂ arta metodei Greedy. Se poate demonstra (prin „exchange argument": orice soluție optimă poate fi transformată, pas cu pas, în cea dată de greedy) că sortarea după ora de final e mereu optimă. Criteriul greșit → răspuns greșit.
5

Numărul minim de săli

Acum vrem să programăm TOATE spectacolele, nu doar câteva. De câte săli avem nevoie, la minim, ca nimic să nu se suprapună?

spectacolele sunt sortate după ora de ÎNCEPUT — apasă Pas 👆
Strategia lacomă: sortezi după ora de început; fiecare spectacol îl pui în prima sală liberă (unde ultimul spectacol s-a terminat deja), iar dacă nu există niciuna → deschizi o sală nouă.
De ce e minimul? Adâncimea = numărul maxim de spectacole care se suprapun în același moment. Evident, ai nevoie de cel puțin atâtea săli — iar greedy folosește exact atâtea. Aici adâncimea e 3 → 3 săli.
6

Problema rucsacului

Un rucsac duce cel mult Gmax kg. Fiecare obiect are o greutate și un câștig. Ce încarci ca să obții câștig maxim? Cheia lacomă: eficiența = câștig / greutate.

Gmax = 10. Obiectele (deja sortate descrescător după eficiență):

apasă „Umple rucsacul" — obiectele intră în ordinea eficienței 👆

📦 Varianta discretă

Obiectele NU se pot tăia — iei un obiect întreg doar dacă mai încape. Aici: 4, 2, 1 (greutate 6, câștig 19). Obiectul 3 (8 kg) nu mai încape.

🔪 Varianta continuă

Obiectele SE pot tăia — umpli restul cu o fracțiune. Aici: 4, 2, 1 + ½ din obiectul 3 (mai încap 4 kg din 8) → câștig 19 + 4 = 23, rucsac plin.

Onest despre optimalitate: greedy pe eficiență e GARANTAT optim la varianta continuă. La varianta discretă (0/1) e o metodă bună, dar nu întotdeauna optimă — optimul deplin se obține cu programare dinamică (clasa a XI-a).
7

Când lacomul pierde — contraexemplul

Greedy nu garantează mereu optimul. O monedă exotică e de-ajuns ca să-l păcălească:

😈 Monede de 1, 3 și 4 · rest = 6

Greedy: 4 + 1 + 1 // 3 monede
Optim: 3 + 3 // 2 monede!

Lacomul ia 4 (cea mai mare!) și se blochează în mărunțiș. Alegerea local optimă NU a dus la optimul global.

😇 De ce merge la 50/10/5/1?

Sistemul monetar real e construit special: fiecare bancnotă e „acoperită" de cele mai mici (50 = 5×10, 10 = 2×5, 5 = 5×1). La astfel de sisteme, lăcomia chiar E optimă. Morala BAC: Greedy se folosește când poți JUSTIFICA de ce alegerea locală nu strică viitorul — altfel, contraexemplul te așteaptă.

Algoritmul casierului, mai rău: cu monede de 8, 7, 5, suma 14 nu poate fi plătită deloc de greedy (8 + 5 + … rămâne 1, imposibil!), deși optimul e clar: 7 + 7. Greedy nici măcar nu găsește o soluție, darămite optimul.
Greedy vs Divide et impera (M11): divide et impera sparge problema și rezolvă TOT, recursiv; Greedy nu sparge nimic — merge înainte cu alegeri definitive, în O(n) sau O(n·log n) (cât costă sortarea). Rapid, dar de verificat!
8

Verificare rapidă

Opt întrebări despre metoda Greedy și problemele ei clasice.

9

Exerciții

De la mână la tastatură — de la ★ (pe hârtie) la ★★★ (cu demonstrație).

🎒 Rucsacul

#CerințăNivel
1Pentru Gmax = 15 și obiectele g = (4, 5, 6, 3), c = (10, 20, 18, 9): calculează eficiențele, apoi rezolvă varianta discretă și continuă.
2Implementează în C++ varianta discretă: structură cu (greutate, profit, nr, ales), sortare descrescătoare după eficiență, umplere cât încape.★★
3Extinde la varianta continuă: după ce nu mai încape un obiect întreg, adaugă fracțiunea din el care umple exact rucsacul.★★

⏳ Coada & ⭐ Spectacole

#CerințăNivel
4Timpi de servire 4, 2, 8, 1, 7: găsește ordinea care minimizează timpul mediu de așteptare și calculează-l.
5Se dau 6 intervale de spectacole. Determină numărul maxim care încap într-o singură sală (sortare după final).★★
6Aceleași 6 intervale: câte săli minim sunt necesare ca să încapă TOATE? (sortare după început, adâncime).★★
7Găsește un sistem de monede și o sumă pentru care greedy dă un răspuns neoptim. Demonstrează cu numere.★★★
Antrenament pe pbinfo.ro: caută categoria „Metoda Greedy" — începe cu restul și spectacolele, continuă cu rucsacul și planificările.
10

Fișa de sinteză

Metoda Greedy, condensată.

Principiul: la fiecare pas, alegerea local optimă — definitivă, fără revenire.
Rețeta: ① (de obicei) sortează după criteriul lacom · ② parcurge și alege ce trece criteriul · ③ nu te întoarce.
Suma maximă: ia toate numerele pozitive → O(n), față de O(2ⁿ) prin forță brută.
Restul: mereu bancnota maximă care încape (algoritmul casierului).
Coada: sortează crescător după timpul de servire → timp mediu de așteptare minim.
Spectacole (o sală): sortează după ora de FINAL → număr maxim de spectacole.
Minim de săli: sortează după ora de ÎNCEPUT; sală liberă sau sală nouă → adâncimea.
Rucsac: sortează descrescător după eficiența câștig/greutate; continuu = optim, discret = doar bun.
Arta = criteriul: la spectacole „după final" e corect; „început"/„durată" — capcane!
Nu garantează optimul: monede 1/3/4, rest 6 → Greedy 3, optim 2. Caută contraexemplul!
Costul: o sortare + o parcurgere → O(n·log n); fără recursivitate, fără stivă.
Exersează: pe pbinfo.ro, categoria „Metoda Greedy" — începe cu restul și spectacolele, apoi rucsacul și planificările.
← anteriorModul 11 · Divide et impera urmează →Modul 13 · Recapitulare finală