Sunteți pe pagina 1din 5

Programare Dinamică. Memoizare.

Alexandru Neagu
5 noiembrie 2022

1 Introducere
Programarea dinamică este o paradigmă de programare care este caracteristică,
de obicei, următoarelor tipuri de probleme:

• Probleme computat, ionale ı̂n care trebuie să determinăm un anumit


rezultat (maxim/minim), influent, at de deciziile pe care le luăm pe
parcurs.
* Cea mai lungă subsecvent, ă dintre două s, iruri de caractere
* Subs, irul de sumă maximă dintr-un tablou
• Probleme computat, ionale ı̂n care trebuie să numărăm o anumită
particularitate din instant, a problemei.
* Câte s, iruri de caractere de lungime n, satisfac proprietatea dată ı̂n
cerint, ă?

• Probleme de decizie ı̂n care decidem dacă un anumit rezultat se poate


ı̂ntâmpla sub anumite circumstant, e
* Câs, tigătorul unui joc, dacă ambii participant, i efectuează mutări
optime

1.1 Cum ne dăm seama că problema este DP?


În general, este dificil să concluzionăm că problema care stă ı̂n fat, a noastră
este rezolvabilă cu programare dinamică. Chiar dacă problema face parte din
categoriile enunt, ate mai sus, există oricum o posibilitate ca ea să se rezolve
folosind paradigma greedy, divide et impera, sau chiar combinatorică. Există
două proprietăt, i care ar putea sugera ı̂nsă aplicarea programării dinamice

1
• Substructura optimă
– Problema poate fi descompusa in subprobleme, iar solutia optima a
problemei depinde de solutiile optime ale subproblemelor
– Aceasta proprietate nu indica neaparat o solutie prin programare
dinamica, deoarece solutii ce utilizeaza metoda Greedy sau Divide et
Impera pot respecta proprietatea
• Subprobleme care se suprapun
– Deoarece subproblemele se suprapun, o rezolvare prin Divide et
Impera ar fi extrem de costisitoare ca si timp de executie, datorita
rezolvarii aceleasi subprobleme de mai multe ori. Prin urmare, prin
programare dinamica, vom rezolva problemele o singura data si vom
retine rezultatele pentru a fi folosite in viitor

1.2 Pas, ii de rezolvare


• Identificăm subproblemele problemei date s, i decidem de ce parametri avem
nevoie pentru a le defini.
• Alegem o structură de date ı̂n care vom ret, ine solut, iile subproblemelor
• Găsim o relat, ie de recurent, ă prin care putem calcula solut, ia problemei
folosind solut, iile subproblemelor
• Rezolvăm relat, ia de recurent, ă ı̂n mod bottom-up (de la cea mai mică
subproblemă la cea mai mare) sau top-down (de la cea mai mare
subproblemă). Rezolvarea top-down este deobicei recursivă s, i utilizează
as, a numita tehnică de memoizare.

– Practic, atunci când implementăm top-down, efectuăm un


backtracking memoizat. Mergem recursiv peste toate subproblemele
stării curente (conform relat, iei de recurent, ă), procesăm rezultatul s, i
ı̂l salvăm ı̂ntr-o structură de date ca să poată fi obt, inut ı̂n O(1) pe
viitor. Această metodă este de multe ori mai us, or de ı̂nt, eles decât
bottom-up, ı̂nsă este greu de intuit complexitatea finală a
algoritmului.
– Atunci când implementăm bottom-up, trebuie să init, ializăm anumite
stări init, iale. De obicei, se init, ializeaza as, a-zisele stări care corespund
subproblemelor triviale din problema noastră. După init, ializare, se
parcurg toate stările (subproblemele) de la cele mai mici la cele mai
mari s, i se află rezultatul ı̂n timp O(1), folosindu-ne de rezultatele
subproblemelor mai mici. Este foarte us, or de stabilit complexitatea
de timp a acestei metode. Ordinea ı̂n care parcurgem stările este un
alt factor foarte important de decis.
• Etapă opt, ională - reconstituirea drumului

2
2 Definirea Subproblemei
Pentru a aplica tehnica programării dinamice, trebuie să definim o
subproblemă = o instant, ă a problemei sugestivă parametrizată. De exemplu,
putem presupune că ı̂ntr-o problemă unde avem doua numere ı̂ntregi ca input
- a s, i b, să considerăm că programarea dinamică va fi bazată pe:
• Subprobleme cu numărul a diferit, iar b constant

• Subprobleme cu numărul a constant, iar b diferit


• Subprobleme cu numerele a s, i b diferite

3 Definirea Structurii De Bază


În cadrul programării dinamice, avem nevoie de o structură de date ce să
memoreze rezultate subproblemelor. Aceste structuri au numărul de
dimensiuni egal cu numărul de parametrii variabili. Într-o problemă ce are ca
input două numere ı̂ntregi a s, i b vom avea:

• Un vector ca structură de bază dacă doar a ori doar b variază


• O matrice dacă s, i a s, i b variază
În cazul ı̂n care avem un vector s, i a constant, la pozit, ia i vom stoca solut, ia
subproblemei pentru perechea input (a, i). În caz de b este constant, la pozit, ia
i vom stoca solut, ia subproblemei pentru perechea input (i, b). În cazul ı̂n care
avem o matrice suport (deci a s, i b sunt variabile), ı̂n celula (i, j) vom avea
solut, ia instant, ei (i, j).

4 Definirea Relat, iei De Recurent, ă


În cadrul relat, iei de recurent, ă există doi pas, i:
• Cazul de bază este reprezentat de subproblema pe care o putem rezolva
trivial
• Formula ce rezolvă o subproblemă, bazându-ne pe alte subprobleme.
– Dacă avem un vector suport, putem obt, ine rezultatul subproblemei
i, folosindu-ne de rezultatele subproblemelor deja calculate j (j < i)
– Dacă avem o matrice suport, putem obt, ine rezultatul subproblemei
(i, j), folosindu-ne de rezultatele subproblemelor deja calculate
(i2, j2), (i > i2 sau i == i2 s, i j >= j2)

3
5 Reconstituirea drumului
În unele probleme, nu se cere doar un număr simbolizând un maxim ori un
minim, ci s, i solut, ia aferentă. Cu alte cuvinte, dacă ne ı̂ntreabă sunt obiectele ce
trebuie alese pentru a obt, ine maximul, trebuie să implementăm o reconstituire
a drumului pentru a vedea cum am ajung la rezultatul maxim din programarea
dinamică. Pentru acest lucru, se construies, te o structură similară, peste care
vom aplica o altă dinamică: â

• În celula i sau (i, j) (depinde ce structură folosim) vom ret, ine celula din
care am ajuns aici. De exemplu, am pus rezultatul ı̂n celula (i, j) bazându-
ne pe celula (i-1, j) ı̂n dinamica principală, deci ı̂n dinamica secundara vom
memora perechea (i-1, j) ı̂n celula (i, j)

• Pentru a reconstitui, parcurgem invers din celula rezultat spre celula de


bază, urmărind indicat, iile din dinamica secundară.

6 Probleme discutate la oră


• Pie Rules −→ solut, ie
• Segments −→ solut, ie
• Rotating Substrings −→ solut, ie

7 Alte Probleme
Ca temă, analizat, i s, i ı̂ncercat, i să rezolvat, i măcar 4 probleme
1. Cladire

2. Numar Submultimi
3. Alpin
4. Lacusta
5. Antivirus

6. Divide The String


7. Bob
8. Asimilation
9. Red Black Number

10. The least round way


11. Drumuri 1

4
References
[1] Vlad Teodorescu - Programare dinamică
https://profs.info.uaic.ro/~infogim/2021/lectii/1112/02%
20dinamica.pdf
[2] Alexandru Lungu - Tehnici de Programare

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