Note de curs, probleme algoritmică, 20 ianuarie 2014

From Algopedia
Jump to navigationJump to search

În acest curs am discutat problemele:

Binary Lexicographic Sequence

Cerință

Se iau în considerare toate secvențele de 0 și 1 de lugime N, care nu conțin două cifre de 1 consecutive. Se cere afișarea celei de-a K-a secvențe în ordine lexicografică.

Rezolvare

Inițial, va trebui să calculăm numărul de astfel de secvențe de o anumită lungime.

Secvențele de lungime 1 sunt în număr de 2:

0
1

Secvențele de lungime 2 sunt în număr de 3:

00
01
10

Secvențele de lungime 3 sunt în număr de 5:

000
001
010
100
101

Secvențele de lungime 4 sunt în număr de 8:

0000
0001
0010
0100
0101
1000
1001
1010

Se observă că secvențele de lungime L se pot obține din mulțimea secvențelor de lungime L - 1 (prin adăugarea cifrei 0 în fața fiecări secvențe) reunită cu mulțimea secvențelor de lungime L - 2 (prin adăugarea cifrelor 10 în fața fiecărei secvențe).

Astfel, putem calcula funcția:

F(L) = numărul de secvențe de lungime L
F(1) = 2
F(2) = 3
F(L) = F(L - 1) + F(L - 2)

După calcularea valorilor funcției F putem determina forma celei de-a K-a secvență de lungime N.

Inițial, va trebui să determinăm dacă cea de-a K-a secvență de lungime N începe cu cifra 0 sau cu cifrele 10. Știind că secvențele care încep cu 0 sunt primele în ordine lexicografică și în număr de F(N - 1) putem deduce că:

K <= F(N - 1)  <=> secvența începe cu 0
K >  F(N - 1)  <=> secvența începe cu 10

În continuare, va trebui să reducem problema la un caz mai simplu (secvențe de lungimi mai mici) și să determinăm restul secvenței după aceeași regulă până la final.

Binary Apple Tree

Cerință

Dându-se un arbore binar ponderat (cu costuri pe muchii), orientat (cu rădăcină fixată) cu N noduri, să se taie Q muchii ale sale, astfel încât suma muchiilor rămase să fie maximă (rădăcina nu poate fi tăiată).

Rezolvare

Problema se rezolvă prin programare dinamică (compunând soluțiile unor subprobleme ale problemei inițiale putem obține rezultatul acesteia).

Vom defini funcțiile:

cost(nod, fiu) = ponderea muchiei care unește nodurile nod și fiu

Muchii(nod) = numărul de muchii din subarborele definit de nodul nod

OptimFF(nod, taiat) = suma maximă posibilă a muchiilor din subarborele definit
                      de nodul nod, dacă din acesta se taie taiat muchii
                      și ambii săi subarbori complet
OptimTF(nod, taiat) = suma maximă posibilă a muchiilor din subarborele definit
                      de nodul nod, dacă din acesta se taie taiat muchii
                      și subarborele său drept complet
OptimFT(nod, taiat) = suma maximă posibilă a muchiilor din subarborele definit
                      de nodul nod, dacă din acesta se taie taiat muchii
                      și subarborele său stâng complet
OptimTT(nod, taiat) = suma maximă posibilă a muchiilor din subarborele definit
                      de nodul nod, dacă din acesta se taie taiat muchii
                      și niciunul din subarborii săi complet

Optim(nod, taiat) = suma maximă posibilă a muchiilor din subarborele definit
                    de nodul nod, dacă din acesta se taie taiat muchii

Acestea se vor calcula după următoarele formule:

Muchii(nod) = 0                                      , dacă nod nu are fii (este frunză)
            = 2 + Muchii(fiuStang) + Muchii(fiuDrept), dacă nod are 2 fii

OptimFF(nod, taiat) = 0, taiat = Muchii(nod)
OptimFT(nod, taiat) = Optim(fiuDrept, taiatDreapta) + cost(nod, fiuDrept),
                          taiat = taiatDreapta + Muchii(fiuStanga) + 1
OptimTF(nod, taiat) = Optim(fiuStang, taiatStanga) + cost(nod, fiuStang),
                          taiat = taiatStanga + Muchii(fiuDreapta) + 1
OptimTT(nod, taiat) = min(Optim(fiuStang, taiatStanga) + cost(nod, fiuStang)
                    + Optim(fiuDrept, taiatDreapta) + cost(nod, fiuDrept),
                          taiat = taiatStanga + 1 + taiatDreapta + 1)

Optim(nod, taiat) = min(OptimFF(nod, taiat), OptimFT(nod, taiat),
                    OptimTF(nod, taiat), OptimTT(nod, taiat))

Soluția problemei este:

Raspuns = Optim(radacina, Q), radacina = 1

Complexitate

Pentru a putea calcula răspunsul problemei, va trebui să calculăm funcția Optim pentru toate nodurile și toate numele de muchii tăiate între 0 și Q, așadar:

Complexitate spațiu: O(N * Q).

Pentru a putea calcula valoarea acestei funcții pentru o pereche de parametri avem nevoie de Q operații, așadar:

Complexitate timp: O(N * Q * Q).