Differences

This shows you the differences between two versions of the page.

Link to this comparison view

pa:laboratoare:laborator-02 [2026/03/09 23:52]
radu.nichita [Exerciții]
pa:laboratoare:laborator-02 [2026/03/15 19:10] (current)
aureliu.antonie [Gardurile lui Gigel]
Line 7: Line 7:
 ===== Precizări inițiale ===== ===== Precizări inițiale =====
 <​note>​ <​note>​
-Toate exemplele de cod se găsesc pe pagina [[https://​github.com/​acs-pa/​pa-lab/​tree/​main/​demo/lab04|pa-lab::demo/lab04]].+Toate exemplele de cod se găsesc pe pagina [[https://​github.com/​acs-pa/​pa-lab/​tree/​main/​algorithms/lab02|pa-lab/algorithms/​lab02]].
  
-Exemplele de cod apar încorporate și în textul laboratorului pentru a facilita parcurgerea cursivă a acestuia. ​**ATENȚIE!** Varianta actualizată a acestor exemple se găsește întotdeauna pe GitHub.+Exemplele de cod apar încorporate și în textul laboratorului pentru a facilita parcurgerea cursivă a acestuia. ATENȚIE! Varianta actualizată a acestor exemple se găsește întotdeauna pe GitHub.
 </​note>​ </​note>​
  
-  * Toate bucățile de cod prezentate în partea introductivă a laboratorului (înainte de exerciții) au fost testate. Cu toate acestea, este posibil cadin cauza mai multor factori (formatare, caractere invizibile puse de browseretc.)un simplu copy-paste să nu fie de ajuns pentru a compila codul.+  * Toate bucățile de cod prezentate în partea introductivă a laboratorului (înainte de exerciții) au fost testate. Cu toate acestea, este posibil ca din cauza mai multor factori (formatare, caractere invizibile puse de browser etc) un simplu copy-paste să nu fie de ajuns pentru a compila codul.
   * Vă rugăm să compilați **DOAR** codul de pe GitHub. Pentru raportarea problemelor,​ contactați unul dintre maintaineri. ​   * Vă rugăm să compilați **DOAR** codul de pe GitHub. Pentru raportarea problemelor,​ contactați unul dintre maintaineri. ​
   * Pentru orice problemă legată de conținutul acestei pagini, vă rugam să dați e-mail unuia dintre responsabili.   * Pentru orice problemă legată de conținutul acestei pagini, vă rugam să dați e-mail unuia dintre responsabili.
Line 23: Line 23:
 De asemenea, DP se poate folosi și pentru probleme în care nu căutam un optim, cum ar fi **problemele de numărare**. De asemenea, DP se poate folosi și pentru probleme în care nu căutam un optim, cum ar fi **problemele de numărare**.
  
-Pentru noțiunile prezentate până acum despre DP, vă rugăm să consultați pagina laboratorului ​3.+Pentru noțiunile prezentate până acum despre DP, vă rugăm să consultați pagina ​[[pa:​laboratoare:​laborator-01|laboratorului ​01]].
 ===== Exemple clasice ===== ===== Exemple clasice =====
  
Line 61: Line 61:
  
 == Enunț == == Enunț ==
-Fie un produs matriceal $M = M_1 M_2 ... M_n$. Putem pune paranteze în mai multe moduri și vom obține același rezultat (înmulțire asociativă),​ dar este posibil să obținem un număr diferit de **înmulțiri scalare**.+Fie un produs matriceal $M = M_1 M_2 ... M_n$. Putem pune paranteze în mai multe moduri și vom obține același rezultat (înmulțirea este asociativă),​ dar este posibil să obținem un număr diferit de **înmulțiri scalare**.
  
 Matricea $M_i$ are (prin convenție),​ dimensiunile $d_{i-1} d_{i}$. Matricea $M_i$ are (prin convenție),​ dimensiunile $d_{i-1} d_{i}$.
Line 359: Line 359:
     * $dp[i] = (dp[i-1] + dp[i-4]) \ \% \  MOD$      * $dp[i] = (dp[i-1] + dp[i-4]) \ \% \  MOD$ 
     *      * 
-<​note>​ Așa cum am zis în secțiunea de [[http://​ocw.cs.pub.ro/​courses/​pa/​laboratoare/​laborator-04?&#​sfaturireguli|sfaturi și reguli]] vrem să facem o **parționare** după un anumit **criteriu**:​ în cazul problemei de față, criteriul de parționare este dacă gardul se termină cu o scândură verticală sau orizontală.+<​note>​ Așa cum am zis în secțiunea de [[http://​ocw.cs.pub.ro/​courses/​pa/​laboratoare/​laborator-02?&#​sfaturireguli|sfaturi și reguli]] vrem să facem o **parționare** după un anumit **criteriu**:​ în cazul problemei de față, criteriul de parționare este dacă gardul se termină cu o scândură verticală sau orizontală.
  
  
-De asemenea, tot în secțiunea [[http://​ocw.cs.pub.ro/​courses/​pa/​laboratoare/​laborator-04?&#​sfaturireguli|sfaturi și reguli]] am precizat că nu vrem **să număram un obiect** (un mod de a construi gardul) **de două ori**. Recurența noastră (dp[i] = dp[i-1] + dp[i-4]) nu ia un obiect de două ori pentru că orice soluție care vine din dp[i-4] e diferită de alta care vine din dp[i-1] pentru că diferă în cel puțin ultima scândură așezată) </​note> ​+De asemenea, tot în secțiunea [[http://​ocw.cs.pub.ro/​courses/​pa/​laboratoare/​laborator-02?&#​sfaturireguli|sfaturi și reguli]] am precizat că nu vrem **să număram un obiect** (un mod de a construi gardul) **de două ori**. Recurența noastră (dp[i] = dp[i-1] + dp[i-4]) nu ia un obiect de două ori pentru că orice soluție care vine din dp[i-4] e diferită de alta care vine din dp[i-1] pentru că diferă în cel puțin ultima scândură așezată) </​note> ​
  
 == Implementare recurență == == Implementare recurență ==
Line 409: Line 409:
 De multe ori, este nevoie să folosim câteva tehnici pentru a obține performanța maximă cu recurența găsită. De multe ori, este nevoie să folosim câteva tehnici pentru a obține performanța maximă cu recurența găsită.
  
-În prima parte a laboratorului ​se menționa tehnica de memoizare. În acesta, ne vom rezuma la cum putem folosi cunoștințele de lucru matriceal pentru a favoriza implementarea unor anumite tipuri de recurențe.+În prima parte a [[pa:​laboratoare:​laborator-01|laboratorului ​01]] se menționa tehnica de **memoizare**. În acesta, ne vom rezuma la cum putem folosi cunoștințele de lucru matriceal pentru a favoriza implementarea unor anumite tipuri de recurențe.
  
 ==== Exponențiere pe matrice pentru recurențe liniare ==== ==== Exponențiere pe matrice pentru recurențe liniare ====
Line 498: Line 498:
 $$S_i = S_{k}C^{i -k}$$ $$S_i = S_{k}C^{i -k}$$
  
 +Pentru a aduce un plus de viteză, vom folosi un truc numit [[https://​en.wikipedia.org/​wiki/​Exponentiation_by_squaring|exponențiere rapidă]]. Pe scurt, vom ridica o valoare(notată $a$) la puterea n, împărțind ​ n folosind reprezentarea sa binară.
  
-În laboratorul ​2 (Divide et Imperaam învățat că putem calcula $^ n$ în timp logaritmic. Deoarece ​și înmulțirea matricilor ​este asociativă, putem calcula $n$ in timp logaritmic.+De exemplu, dacă am vrea să calculăm:​ 
 +$$ 5^{13} = 5^{1101_2}= 5^8 * 5^4 * 5^1 $$ 
 + 
 +Exponentul are exact $\lfloor log_2(n) \rfloor + 1$ cifre în baza 2, deci vom avea nevoie de $O(log(n))$ înmulțiri, fiind condiționați de faptul ​că trebuie să cunoaștem $a^1, a^2, a^4, etc.$ Din fericire, ​putem calcula ​rapid acești factori prin ridicarea la pătrat a elementului precedent. 
 + 
 +În final, putem implementa un algoritm iterativ pentru calcularea rezultatului ​$a^n$ iterând prin cifrele din baza 2 ale lui n și înmulțind cu ${a^2}^{k}$ atunci când cifra curentă ​este 1(pentru viteză, vom folosi operații pe biți în loc de o iterare propriu zisă prin cifre). 
 + 
 +Mai jos putem vedea o implementare in C++: 
 +<code cpp> 
 +long long pow(long long a, long long n) { 
 +    long long res = 1; 
 +    while (n > 0) { 
 +        // daca cel mai nesemnificativ bit(LSB) din n este 1 
 +        if (n & 1) { 
 +            res = res * a; 
 +        } 
 +         
 +        // calculam urmatorul factor 
 +        a = a * a; 
 +         
 +        // shiftam la dreapta n cu o pozitie(urmatorul bit va deveni LSB) 
 +        n >>= 1; 
 +    } 
 +    return res; 
 +
 +</​code>​ 
 + 
 +Acest truc poate fi folosit pentru orice tip de date pentru care înmulțirea este asociativă(inclusiv matrice).
  
 Obținem astfel o soluție cu următoarele complexități:​ Obținem astfel o soluție cu următoarele complexități:​
Line 643: Line 671:
 ===== Pool probleme (pentru prezentări) ====== ===== Pool probleme (pentru prezentări) ======
  
-<​hidden>​ +======= 1) Rectangle Cutting =======
- +
-======= 1) Burst Balloons ======= +
- +
-**Enunt:​** ​  +
-Se dau ''​n''​ baloane, fiecare având un număr asociat. Când spargi balonul ''​i'',​ câștigi monede egale cu produsul numerelor de pe balonul ''​i''​ și baloanele vecine lui în acel moment. ​  +
-După spargere, balonul dispare, iar vecinii lui devin adiacenți. La extremități se consideră două baloane imaginare cu valoarea 1.   +
- +
-Determinati numărul maxim de monede pe care îl puteți obține spargând toate baloanele într-o anumită ordine. +
- +
-**Date de intrare:​** ​  +
-Un vector de ''​n''​ numere întregi care reprezintă valorile baloanelor. +
- +
-**Date de ieșire:​** ​  +
-Se afișează un singur număr întreg — numărul maxim de monede ce poate fi obținut. +
- +
-Problema se poate testa la:   +
-https://​leetcode.com/​problems/​burst-balloons/​description/​ +
- +
-======= 2) Rectangle Cutting =======+
  
 **Enunt:​**  ​ **Enunt:​**  ​
-Se dă un dreptunghi de dimensiuni ''​a × b''​. ​Puteți ​face tăieturi doar pe linii paralele cu laturile dreptunghiului,​ împărțind dreptunghiul în două dreptunghiuri mai mici.  ​+Se dă un dreptunghi de dimensiuni ''​a × b''​. ​Se pot face tăieturi doar pe linii paralele cu laturile dreptunghiului,​ împărțind dreptunghiul în două dreptunghiuri mai mici.  ​
  
 Determinati numărul minim de tăieturi necesare pentru a împărți dreptunghiul în pătrate. Determinati numărul minim de tăieturi necesare pentru a împărți dreptunghiul în pătrate.
Line 678: Line 687:
 https://​cses.fi/​problemset/​task/​1744 https://​cses.fi/​problemset/​task/​1744
  
-======= ​3) Removal Game =======+======= ​2) Removal Game =======
  
 **Enunt:​**  ​ **Enunt:​**  ​
Line 696: Line 705:
 https://​cses.fi/​problemset/​task/​1097/​ https://​cses.fi/​problemset/​task/​1097/​
  
-======= ​4) Array Description =======+======= ​3) Array Description =======
  
 **Enunt:​**  ​ **Enunt:​**  ​
-Se dă un vector de lungime ''​n''​. Fiecare element ​trebuie să fie un număr între 1 și ''​m''​. Unele poziții sunt deja fixate, iar altele au valoarea 0, ceea ce înseamnă că pot fi alese liber.  ​+Se dă un vector de lungime ''​n''​. Fiecare element ​este un număr între 1 și ''​m''​. Unele poziții sunt deja fixate, iar altele au valoarea 0, ceea ce înseamnă că pot fi alese liber.  ​
 Un vector este valid dacă diferența absolută dintre două elemente consecutive este cel mult 1.  ​ Un vector este valid dacă diferența absolută dintre două elemente consecutive este cel mult 1.  ​
  
Line 714: Line 723:
 https://​cses.fi/​problemset/​task/​1746/​ https://​cses.fi/​problemset/​task/​1746/​
  
-======= ​5) Student Attendance Record II =======+======= ​4) Student Attendance Record II =======
  
 **Enunt:​**  ​ **Enunt:​**  ​
-Un elev are un istoric ​de prezență pe parcursul a ''​n''​ zile. Pentru fiecare zi, înregistrarea ​poate fi:   +Un elev are un istoric ​al prezentețor la școală pe parcursul a ''​n''​ zile. Pentru fiecare zi, status-ul său  ​poate fi:   
-P (present) — prezent ​  +    ​*  ​P (present) — prezent ​  
-L (late) — întârziat ​  +    ​* ​L (late) — întârziat ​  
-A (absent) — absent  ​+    ​* ​A (absent) — absent  ​
  
 Un istoric este considerat valid dacă:  ​ Un istoric este considerat valid dacă:  ​
-conține cel mult o absență (A)   +    * conține cel mult o absență (A)   
-nu conține mai mult de două întârzii ​consecutive (L)  ​+    ​* ​nu conține mai mult de două întârzieri ​consecutive (L)  ​
  
 Determinati câte istorice de prezență valide de lungime ''​n''​ există. Determinati câte istorice de prezență valide de lungime ''​n''​ există.
Line 737: Line 746:
 https://​leetcode.com/​problems/​student-attendance-record-ii/​description/​ https://​leetcode.com/​problems/​student-attendance-record-ii/​description/​
  
-</hidden>+======= 5) Burst Balloons ======= 
 + 
 +**Enunt:​** ​  
 +Se dau ''​n''​ baloane, fiecare având un număr asociat. Când se sparge balonul ''​i'',​ se câștigă un număr de monede egale cu produsul numerelor de pe balonul ''​i''​ și baloanele vecine lui în acel moment. ​  
 +După spargere, balonul dispare, iar vecinii lui devin adiacenți. La extremități se consideră două baloane imaginare cu valoarea 1.   
 + 
 +Determinati numărul maxim de monede pe care îl puteți obține spargând toate baloanele într-o anumită ordine. 
 + 
 +**Date de intrare:​** ​  
 +Un vector de ''​n''​ numere întregi care reprezintă valorile baloanelor. 
 + 
 +**Date de ieșire:​** ​  
 +Se afișează un singur număr întreg — numărul maxim de monede ce poate fi obținut. 
 + 
 +Problema se poate testa la:   
 +https://​leetcode.com/​problems/​burst-balloons/​description/​ 
 ===== Extra (studiu de caz pentru acasă) ===== ===== Extra (studiu de caz pentru acasă) =====
 <spoiler Por Costel si Azerath> <spoiler Por Costel si Azerath>
pa/laboratoare/laborator-02.1773093143.txt.gz · Last modified: 2026/03/09 23:52 by radu.nichita
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0