Sunteți pe pagina 1din 2

Laborator 5 - Programare Dinamica

0. Arbori optimali de acoperire:


Citit urmatorul link - https://www.geeksforgeeks.org/optimal-binary-search-tree-dp-24/
Sa se analizeze pentru Input: keys[] = {10, 12, 20, 30}, freq[] = {34, 8, 50, 40} care e costul ce mai
bun pentru arborele de cautare asociat.

Construim D[i][j] = costul celui mai bun arbore de cautare pentru cheile intre i si j.
D[1][1] = 34
D[2][2] = 8
D[3][3] = 50
D[4][4] = 40
Folosim formula D[i][j] = sum_freq(i, j) + min(D[i][r-1]+D[r+1][j]), r=i...j =>
D[1][2] = 34+8 + min(8,34) = 42+8 = 50
D[2][3] = 8 + 50 + min(8,50) = 58+8 = 64
D[3][4] = 50+40 + min(50,40) = 130
Trecem la nivelul urmator, de 3 noduri =>
D[1][3] = 34+8+50+min(64, 84, 50) = 92+50 = 142 (corespunde sa marcam nodul cu frecventa 50 root)
D[2][4] = 8+50+40+min(130, 48, 64) = 98+48 = 146 (la fel, nodul cu frecventa 50 e root)
Solutia:
D[1][4]= 34+8+50+40+min(146, 34+130,50+40,142) = 132+90 = 222

Arborele arata in felul urmator:

20
10 30
12
Cost: 1*50 + 2*34+2*40+3*8 = 50+ 68 + 80 +24 = 222, verifica solutia

1. k-garduri
Putem forma un k-gard in mai multe moduri, punand scanduri pe verticala sau orizontala. O scandura
are dimensiunea kx1 iar gardul are inaltime k, deci ca sa putem pune o scandura pe orizontala lungimea
gardului trebuie sa fie minim k. De ex, pentru lungime k avem 2 variante – k scanduri puse pe verticala
sau k scanduri puse pe orizontala. Pentru lungime k+1, putem adauga o scandura pe verticala la un gard
de lungime k, care se poate face in 2 moduri, sau putem adauga k scanduri pe orizontala la un gard de
lungime 2, deci avem 3 solutii posibile. Cate solutii posibile avem pentru lungime N?

Recurenta: D[i] = nr de solutii pt lungime I


D[i] = D[i-1] + D[i-k], din motivele mentionate mai sus

2. Dandu-se un sir de numere naturale, cate sume putem forma care sa aiba restul 0 la impartirea cu 3?
Solutie:
Tinem urmatoarea dinamica: D[i][j] = cate sume putem forma, sa se termine cel mult pe pozitia i si sa
aiba restul j la impartirea cu 3. Recurentele sunt destul de evidente:
daca v[i]%3==0 =>
D[i][0] = 1+2*sum(D[j][0]), j=1...i-1 (putem adauga v[i] sau nu la solutiile precedente sau il luam doar
pe v[i])
D[i][1] = 2*sum(D[j][1]), j=1...i-1
D[i][2] = 2*sum(D[j][2]), j=1...i-1
v[i]%3 == 1 =>
D[i][0] = sum(D[j][0])+sum(D[j][2]), j=1...i-1
D[i]1] = 1+sum(D[j][0])+sum(D[j][1]), j=1..i-1
D[i][2] =sum(D[j][2]+sum(D[j][1]), j=1...i-1
v[i]%3==2 =>
D[i][0] = sum(D[j][1])+sum(D[j][0]), j=1...i-1
D[i]1] = sum(D[j][2])+sum(D[j][1]), j=1..i-1
D[i][2] =sum(D[j][0])+1+sum(D(j][2]), j=1...i-1
Solutia finala este D[n][0].

Problema extra:
1. k- Garduri eficiente:
Sa se rezolve dinamica in complexitate logaritmica folosind inmultire de matrici.

Se considera la fiecare pas urmatorul vector:


S(i) = [D[i-k+1], D[i-k+2],… D[i])
Observam ca putem obtine
S(i) = S(i-1) * M, unde
M = [0 0 0… 0 1
1 0 0... 0 0
0 1 0… 0 0
..
0 0 0… 1 1]

Avand in vedere ca S(i) = S(i-1)*M => S(n) = S(k) * M^(n-k). Inmultirea se poate face in timp
logaritmic cu divide et impera.

Sume pe matrici – Dandu-se o matrice binara, sa se stabileasca cate submatrice de dimensiune k x k


sunt pline de 1, pentru fiecare k in parte.
Solutie
Se calculeaza D[i][j] = cea mai mare submatrice plina de 1 cu coltul dreapta jos pe pozitia (i,j).
D[i][j] = min (D[i-1][j], D[i]j-1],D[i-1][j-1])+1, daca M[i][j] = 1. Pe masura ce calculam D[i][j],
actualizam si S[i] = cate submatrice de dimensiune i x i sunt pline de 1.

S-ar putea să vă placă și