Sunteți pe pagina 1din 12

Tehnici de programare

Metoda Greedy

Esena metodei:
Fie dat problema P cu spaiul de soluii:
S = {s1, s2, , sN}
i restriciile R
P cere s se determine n S o submulime
Q* = {q1, q2, , qK}, astfel nct:
Q* = max {Q1, Q2, , QR}, R=2N
C

C criteriul de selecie soluiei.

Esena metodei (2)


Pentru obinerea soluiei Greedy
1. Se sorteaz elementele din S n msura
descreterii corespunderii criteriului C.
Se obine irul sortat: s*1, s*2, , s*N.
2. Se consider soluia iniial vid B
3. Se adaug consecutiv n B elementele s*1, s*2,
, s*i , att timp ct nu se ncalc restriciile
R ale problemei P.

Esena metodei (3)


Mai puin formalizat, metoda poate fi descris astfel:
Din mulimea de elemente S se alege acel element
s* care satisface cel mai bine criteriul C de
includere n soluie. Dac adugarea s* la soluia
curent nu contravine restriciilor R ale problemei,
acesta se include n soluie. n caz contrar el se
exclude din mulimea elementelor disponibile
pentru adugare.

Problem tip
Fie un set S de N (N<100) segmente pe axa
0X.
Pentru fiecare segment si este cunoscut
abscisa extremitii stngi xi i lungimea sa
li.
S se scrie un program, care va determina
un subset cu un numr maxim de segmente,
S* S, astfel nct segmentele din S* nu se
vor intersecta ntre ele.

Analiz
Criteriul C: cel mai bun segment este cel care se
sfrete primul.
Restricia R: nceputul segmentului care se adaug trebuie
s aib abscisa mai mare dect sfritul oricrui dintre
segmentele adugate anterior n soluie.
Structuri de date: fiecare segment va fi descris de un
articol de 2 componente valorile extremitilor, iar setul de
segmente de un tablou de articole:
type segment = record st, dr : integer; end;
tablou = array [1..100] of segment;

Algoritm
1. Se sorteaz elementele din S dup creterea
coordonatei extremitii drepte.
s*1, s*2, , s*N.
Se formeaz soluia iniial B, din primul element
al irului sortat (el nu poate nclca restricia R)
k 1, Bk s*1.
2. Pentru fiecare i de la 2 la N se verific condiia:
Dac s*i.st > bk.dr atunci
k k+1, Bk s*i

Date iniiale
Datele se citesc din fiierul text data.in cu
urmtoarea structur: prima linie a fiierului
conine un numr ntreg N numrul de
segmente. Urmtoarele N linii conin cte 2
numere ntregi, separate prin spaiu abscisa
extremitii stngi xi a segmentului i i
lungimea lui li.

Implementare
type segment=record st,dr : integer; end;
sets = array[1..100] of segment;
var a,b: sets;
n,k: integer;
procedure readdata(var x: sets; var n: integer);
var
f: text;
i,r: integer;
begin
assign(f, 'data.in'); reset(f);
readln(f,n);
for i:=1 to n do
begin
readln(f, x[i].st, r);
x[i].dr:=x[i].st+r;
end;
close(f);
end;

procedure sort (var x:sets; n:integer);


var i,j: integer;
t: segment;
begin
for i:=1 to n -1 do
for j:=1 to n-i do
if x[j].dr>x[j+1].dr then
begin t:=x[j]; x[j]:=x[j+1]; x[j+1]:=t; end;
end;
procedure solve(var y:sets; x:sets; n:integer;
var k:integer);
var i: integer;
begin
y[1]:=x[1]; k:=1;
for i:=2 to n do
if x[i].st > y[k].dr then begin k:=k+1; y[k]:=x[i]; end;
end;

procedure print(x: sets;k:integer);


var i: integer;
begin
writeln(k);
for i:=1 to k do
writeln(x[i].st, ' ',x[i].dr);
end;
begin
readdata(a,n);
sort(a,n);
solve(b,a,n,k);
print(b,k);
end.

Output >

Probleme tip
A.Plata unei sume cu un numr minim de bancnote de
valori date.
Fie dat suma S (S < 30000) i o serie de N (N < 10) tipuri de valori
distincte (fiecare valoare nu depete 1000) a bancnotelor din
bancomat. Numrul de bancnote de fiecare tip se consider infinit.
Scriei un program, care va determina modalitatea de plat a sumei
S cu un numr minim de bancnote.

B.Plata unei sume cu un numr minim de bancnote


n condiiile problemei precedente, numrul de bancnote de fiecare
tip va fi limitat de valorile v1, v2, vn.