Documente Academic
Documente Profesional
Documente Cultură
S0 S1 S2 S3 S4 Sn-1 Sn
1
Programarea Dinamică reprezintă o metodă de rezolvare a problemelor pentru care soluţia
poate fi privită ca rezultatul a unor decizii (D1,D2,D3,...,Dn). Fiecare decizie trebuie să
satisfacă principiul optimalităţii.
b) decizia Dx depinde de deciziile D1, D2,..., Dx-1. In acest caz se aplică metoda Inapoi.
Deciziile se iau în ordinea : D1, D2,..., Dn.
k − 1 k
k + , 0 < k < n
= n − 1 n − 1
n
1, in rest
2
function C(n,k)
DACA (k=0) or (k=n) ATUNCI return 1
ALTFEL return C(n-1,k-1)+C(n-1,k)
SFDACA
3
int comb(int n, int k)
{
int i,j;
int c[20][20];
for( i=0; i<=n ;i++)
{ c[i][0]=1;
c[i][i]=1;
for( j=1;j<= i-1 ;j++)
c[i][j]=c[i-1][j-1]+c[i-1][j];
}
return c[n][k];
}
4
Un algoritm de programare dinamică poate fi descris prin următoarea
succesiune de paşi:
1. se caracterizează structura unei soluţii optime;
2. se obţine recursiv valoarea unei soluţii optime;
3. se calculează de jos în sus valoarea unei soluţii optime;
5
Problema triunghiului
rezultatul va fi 17.
Rezolvare:
Se pot forma mai multe sume:
S1=2+3+6+5=16
S2=2+5+4+1=12
…………….
Sk=2+3+6+6=17 (care este şi suma maximă).
Se observă că se pot forma 2n-1 astfel de sume. A le lua în considerare
pe toate pentru a găsi valoarea optimă (maximă) nu este eficient.
6
Vom forma un triunghi, de la bază către vârf, cu sumele maxime care
se pot forma cu fiecare număr. Dacă am memorat triunghiul de numere
într-o matrice T şi calculăm sumele într-o matrice C, vom avea relaţiile
următoare:
C[n,1]:=T[n,1];
C[n,2]:=T[n,2];
…………
C[n,n]:=T[n,n];
Pentru linia i (i<n), cele i sume maxime se obţin astfel:
C[i,j]:=max{T[i,j]+C[i+1,j], T[i,j]+C[i+1, j+1]}, unde iœ{1,2,…,n-1}
şi jœ{1, …,i}.
Să rezolvăm problema propusă ca exemplu:
Linia 4 a matricii C va fi linia n a matricii T:
5 6 1 4;
Linia 3 se calculează astfel:
C[3,1]=max{6+5,6+6}=12;
C[3,2]=max{3+6,3+1}=9;
C[3,3]=max{4+1,4+4}=8;
Linia 2:
C[2,1]=max{3+12,3+9}=15;
C[2,2]=max{5+9, 5+8}=14;
Linia 1:
C[1,1]=max{2+15,2+14}=17.
Aceasta este şi cea mai mare sumă care se poate forma.
7
#include <stdio.h>
#include <conio.h>
int n,i,j;
int t[20][20],c[20][20],drum[20][20];
void main()
{
printf("nr. linii ale triunghiului ="); scanf("%d",&n);
for(i=1;i<=n;i++)
for(j=1;j<=i;j++)
{
printf("a[%d,%d]=",i,j); scanf("%d",&t[i][j]);
}
for(j=1;j<=n;j++) c[n][j]=t[n][j];
for(i=n-1;i>=1;i--)
{
for(j=1;j<=i;j++)
if (c[i+1][j]<c[i+1][j+1])
{
c[i][j]=t[i][j]+c[i+1][j+1];
drum[i][j]=j+1;
}
else
{
c[i][j]=t[i][j]+c[i+1][j];
drum[i][j]=j;
}
}
8
i=1;
j=1;
while (i<=n)
{
printf("\t %d",t[i][j]);
j=drum[i][j];
i=i+1;
}
printf("\n");
getch();
}
9
Problema pachetelor
n = numărul de pachete
Inst = timpul de instalare a pachetului
D= timpul de descărcare a pachetului
1§ n § 100000
1§ Inst, D § 1000
10
Soluţia fiecărei subprobleme o vom reţine într-un vector min, unde
min[i]= numărul minim de secunde după care poate începe instalarea
aplicaţiei, calculat din momentul începerii descărcării pachetului i, 0 §
i< n.
Relaţia de recurenţă:
• min[n-1]=D[n-1]
(nr. minim de secunde după care poate începe instalarea pachetului
n-1, ultimul pachet, este egal cu timpul necesar descărcării complete
a pachetului n-1)
• min[i]=D[i] + max{0, min(i+1) –Inst[i]}, " 0 § i< n-1.
11
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#define NMAX 1000
#define max(x,y) ((x)>(y)?(x):(y))
FILE *f; // declararea descriptorului de fisier intrare
FILE *g; // declararea descriptorului de fisier iesire
int min[NMAX], D[NMAX], Inst[NMAX];
void main()
{
if((f=fopen("c:\\borlandc\\fin.txt","r"))==0)
{
printf("Fisierul nu poate fi deschis !");
exit(1);
}
if((g=fopen("c:\\borlandc\\fout.txt","w"))==0)
{
printf("Fisierul nu poate fi creat !");
exit(1);
}
int n, i;
fscanf(f,"%d",&n);
for(i=0;i<n;i++)
fscanf(f,"%d%d",&Inst[i],&D[i]);
fclose(f);
min[n-1]=D[n-1];
for(i=n-2;i>=0;i--)
min[i]=D[i]+max(0, min[i+1]-Inst[i]);
fprintf(g, "%d\n",min[0]);
fclose(g);
getch();
}
12