Professional Documents
Culture Documents
In urmatorul articol voi prezenta cateva aplicatii ale acestei tehnici importante
de programare denumita stiintific Greedy.
1.
2.
3.
4.
Descriere
Prezentare
Probleme clasice rezolvate prin metoda Greedy
Exercitii
1.Descriere
Metoda Greedy este una din cele mai directe tehnici de proiectare a algoritmilor
care se aplica la o varietate larga de probleme.In general,aceasta metoda se
aplica problemelor de optimizare.Specificul acestei metode consta in faptul ca
se construieste solutia optima pas cu pas,la fiecare pas fiind selectat(sau
inghitit) in solutie elementul care pare cel mai bunla momentul respectiv,in
speranta ca va duce la solutie optima globala.
2.Prezentare
i s`au propus n (n <= 100) spectacole si pentru fiecare spectacol i`a fost
anuntat intervalul in care se poate desfasura [Si,Fi] (Si reprezinta ora si minutul
de inceput,iar Fi ora si minutul de final al spectacolului i),scrieti un program care
sa permita spectatorilor vizionarea unui numar cat mai mare de spectacole.
B. Exemplu :
spectacole.in
5
12 30 16 30
15 0 18 0
10 0 18 30
18 0 20 45
12 15 13 0
spectacole.out
524
C. Solutie
Ordonam spectacolele crescator dupa ora de final.Selectam initial primul
spectacol(cel care se termina cel mai devreme).La fiecare pas selectam primul
spectacol neselectat,care nu se suprapune cu cele deja selectate(cele care incep
dupa ce se termina ultimul spectacol).
?
#include <stdio.h>
1
2
int n,inceput[100],sfarsit[100],nr[100];
3
4
void citeste();
5
void sorteaza();
6
void rezolva();
7
int main()
8
{
9
freopen("spectacole.in","r",stdin);
10
freopen("spectacole.out","w",stdout);
11
12
citeste();
13
sorteaza();
rezolva();
14
15
fclose(stdin); fclose(stdout);
16
return 0;
17
}
18
19
void rezolva()
{
20
int ultim,i;
21
for(ultim = 0,i = 1; i < n; i++)
if(inceput[nr[i]] >= sfarsit[nr[ultim]]) // se
22
{
23
printf("%d ",nr[i]+1); ultim = i;
24
}
printf("\n");
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
}
void sorteaza()
//ordonam crescator spectacolele dupa ora de final
{
int schimb,i,aux;
do
{
schimb = 0;
for(i = 0; i < n-1; i++)
if(sfarsit[nr[i]] > sfarsit[nr[i+1]])
{
aux = nr[i];
nr[i] = nr[i+1];
nr[i+1] = aux;
schimb = 1;
}
}while(schimb);
}
void citeste()
{
int i,m,h;
scanf("%d",&n);
for(i = 0; i < n; i++)
{
nr[i] = i+1;
scanf("%d %d",&h,&m);
inceput[i] = h * 60 + m;
scanf("%d %d",&h,&m);
//pentru fiecare spectacol transformam ora de sfarsit
sfarsit[i] = h * 60 + m;
rucsac.out
2 100.00%
4 79.00%
5 100.00%
C. Solutie :
Vom reprezenta o solutie a problemei ca un vector x cu n componente,in care
retinem pentru fiecare obiect fractiunea incarcata in rucsac de hot.Deci vectorull
x trebuie sa indeplineasca urmatoarele conditii :
1. Xi E [0,1], V i E { 1,2,n }; //unde E = apartine si V = oricare ar fi
2. G1 * X1 + G2 * X2 + .. + Gn * Xn <= GMax;
3. f(x) = C1 * X1 + C2 * X2 + + Cn * Xn este maxima.
Ordonam obiectele descrescator dupa castigul pe unitatea de greutate(valoare
care constituie o masura a eficientei transportarii obiectelor). Cat timp este
posibil (incap in rucsac),selectam obiectele in intregime.Completam rucsacul cu
un fragment din urmatorul obiect ce nu a fost deja selectat.
?
#include<stdio.h>
1
int o[50]; //ordinea obiectelor
2
float c[100],g[100],x[100],Gr,GMax;
3
int n;
4
5
void citeste();
void sorteaza();
6
void rezolva();
7
void afiseaza();
8
9
int main()
10
{
11
12
freopen("rucsac.in","r",stdin);
freopen("rucsac.out","w",stdout);
13
14
citeste();
15
sorteaza();
16
rezolva();
17
afiseaza();
18
fclose(stdin); fclose(stdout);
19
return 0;
20
}
21
22
void citeste()
23
{
24
scanf("%d%e",&n,&GMax);
for(int i = 0; i < n; i++)
25
{
26
o[i] = i;
27
scanf("%e%e",&c[i],&g[i]); //citim valorile
28
}
29
}
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
void sorteaza()
{
int i,schimb,aux;
do //ordonam obiectele descrescator dupa castigul unitar
{
schimb = 0;
for(i = 0; i < n-1; i++)
if(c[o[i]]/g[o[i]] < c[o[i+1]]/g[o[i+1]])
{
aux = o[i];
o[i] = o[i+1];
o[i+1] = aux;
schimb = 1;
}
}while(schimb);
}
void rezolva()
{
int i;
for(i = 0,Gr = GMax; i < n && Gr > g[o[i]]; i++)
{
x[o[i]] = 1; Gr-= g[o[i]];
}
}
void afiseaza()
{
for(int i = 0; i < n; i++)
if(x[i]) printf("%d %e \n",i+1,x[i] * 100);
}
Aceasta tehnica este folosita intr-un mare numar de probleme si aplicatii printre
care putem aminti :