Ud Program

You might also like

Download as pdf or txt
Download as pdf or txt
You are on page 1of 18

Uvod u dinami cko programiranje

Andreja Ili c e-mail: ilic andrejko@yahoo.com Aleksandar Ili c e-mail: aleksandari@gmail.com

Prirodno Matemati cki Fakultet u Ni su

Uvod

Jedan od cestih algoritamskih problema jeste problem optimizacije: zadati problem mo ze imati vi se re senja, svako re senje ima svoju vrednost, a tra zi se ono koje ima ekstremnu vrednost. U jednoj sirokoj klasi problema optimizacije, re senje mo zemo na ci kori s cenjem dinami ckog programiranja (eng. dynamic programming). Teorijski gledano probleme optimizacije, kao i probleme pretrage, mo zemo re siti simulacijom svih stanja, odnosno obilaskom celokupnog prostora pretrage (eng. backtracking). Ovo je naravno korektan pristup, med utim on nije upotrebljiv za probleme sa velikim brojem stanja. Takod e, mo zemo koristiti grabljivi pristup (eng. greedy algorithm), koji se zasniva na biranju lokalnog najboljeg poteza u svakoj ta cki grananja. Ova vrsta heuristike mo ze znatno smanjiti slo zenost i prostor pretrage, ali se ne mo ze tvrditi njena ta cnost. Ideja dinami ckog programiranja je da se iskoristi princip domina: sve nanizane domine ce popadati ako se poru si prva domina u nizu. Dakle, da bi se re sio neki problem, treba re siti neki njegov manji slu caj (podproblem), a zatim pokazati kako se re senje zadatog problema mo ze konstruisati polaze ci od (re senih) podproblema. Ovakav pristup je baziran na matemati ckoj indukciji.

je dinami Sta cko programiranje?

Dinami cko programiranje je naziv popularne tehnike u programiranju kojom drasti cno mo zemo smanjiti slo zenost algoritma: od eksponencionalne do polinomijalne. Re c programiranje u samom nazivu tehnike se odnosi na tzv. tabli cni metod, a ne na samo kucanje kompjuterskog koda. Sli cno metodi podeli pa vladaj (eng. divide and conquer), dinami cko programiranje re savanje jednog problema svodi na re savanje podproblema. Za ovakve probleme se ka ze da imaju optimalnu strukturu (eng. optimal substructure). Podeli pa vladaj algoritmi vr se particiju glavnog problema na nezavisne podprobleme. Zatim nastupa rekurzivno re savanje podproblema, kako bi se njihovim spajanjem dobilo re senje polaznog problema. Algoritam koji je dobar predstavnik ove klase jeste sortiranje u ce sljavanjem (eng. merge sort), algoritam za sortiranje niza. Dinami cko programiranje (DP) takod e vr si particiju glavnog problema na podprobleme (eng. overlapping subproblems), ali koji nisu nezavisni. Jo s jedna bitna karakteristika DP jeste da se svaki podproblem re sava najvi se jednom, cime se izbegava ponovno ra cunanje numeri ckih karakteristika istog stanja (odatle tabli cni metod, iz prostog razloga sto se, kako cemo ubrzo videti, re senja podproblema cuvaju u pomo cnim tablicama). Opisanu memorizaciju objasnimo na primeru Fibona cijevih brojeva (F1 = F2 = 1, Fn = Fn1 + Fn2 za n > 2). Naivna implementacija rekurzivne funkcije za ra cunanje n-tog Fibona cijevog broja bazirana na deniciji je prikazana u algoritmu A. Primetimo da pri ra cunanju vrednosti F ib(n), funkcije F ib(m) za m < n se pozivaju ve ci broj puta. Za n = 5 imali bi slede ce: F ib(5) = F ib(4) + F ib(3) = (F ib(3) + F ib(2)) + (F ib(2) + F ib(1)) = ((F ib(2) + F ib(1)) + F ib(2)) + (F ib(2) + F ib(1)) 1

Algoritam A: Funkcija F ib(n) za ra cunanje n-tog Fibona cijevog broja


Input: Prirodni broj n Output: n-ti Fibona cijev broj
1 2 3 4

if n 2 then return 1; end return (F ib(n 1) + F ib(n 2));

Med utim ukoliko bi vr sili memorizaciju izra cunatih stanja, ne bi morali da ulazimo u rekurzije brojeva koje smo ve c ra cunali. Deni simo niz f ib[k ] u kome cemo pamtiti Fibona cijeve brojeve koje ra cunamo u rekurzivnim pozivima. Na po cetku inicijalizujmo sve elemente niza na 1 ( cime ih prakti cno markiramo kao neizra cunate). Ovim pristupom izbegavamo nepotrebna ra cunanja. Algoritam B: Funkcija F ib(n) za ra cunanje n-tog Fibona cijevog broja sa memorizacijom
Input: Prirodni broj n Output: n-ti Fibona cijev broj
1 2 3 4 5 6 8

if f ib[n] = 1 then return f ib[n]; end

if n 2 then f ib[n] = 1; end 7 f ib[n] = F ib(n 1) + F ib(n 2); return f ib[n];

Grubo govore ci, strukturu algoritma baziranom na DP, mo zemo opisati u cetiri koraka: 1. Okarakterisati strukturu optimalnog re senja 2. Rekurzivno denisati optimalnu vrednost 3. Izra cunati optimalnu vrednost problema odzgo na gore 4. Rekonstruisati optimalno re senje Kao rezultat prva tri koraka dobijamo optimalnu vrednost. Poslednji korak izvr savamo ukoliko je potrebno i samo optimalno re senje. Pri njegovoj rekonstrukciji obi cno koristimo neke dodatne informacije koje smo ra cunali u koraku 3. Verovatno smo svi jo s u osnovnoj skoli nai sli na standardni problem kusura: prodavac ima diskretan skup nov canica sa vrednostima 1 = v1 < v2 < . . . < vn (beskona cno od svake vrste) i treba vratiti kusur u vrednosti od S nov canih jedinica, pri cemu treba minimizirati broj nov canica. Ukoliko je skup nov canica diskretan i menja se samo vrednost kusura S , problem mo zemo re siti rekurzijom odnosno preko n ugnje zdenih petlji. Med utim, sta se de sava u slu caju kada ni vrednosti nov canica, kao ni njihov broj nisu poznati unapred. Ovaj i mnoge druge probleme mo zemo jednostavno re siti uz pomo c DP-a, dok je ovaj problem jedna verzija problema ranca koji cemo obraditi u poglavlju 4. Kako bi bolje razumeli koncept DP pro ci cemo detaljno kroz naredni problem. Problem 1 [Maksimalna suma nesusednih u nizu] Dat je niz a prirodnih brojeva du zine n. Odrediti podniz datog niza ciji je zbir elemenata maksimalan, a u kome nema susednih elemenata. Podproblem gornjeg problema mo zemo denisati kao: nala zenje tra zenog podniza na nekom delu polaznog niza a. Preciznije, denisa cemo novi niz d na slede ci na cin: 2

d[k ] = maksimalan zbir nesusednih elemenata niza (a1 , a2 , . . . , ak ), za k [1, . . . , n] Re senje polaznog problema ce biti vrednost d[n]. Napomena: Algoritam za denisanja podproblema ne postoji i zavisi od same prirode problema. Nekada morate pro ci nekoliko mogu cnosti kako bi do sli do prave. Naravno, ve zbom i detaljnijom analizom problema se mo ze ste ci neka intuicija, ali univerzalno re senje ne postoji (There is no free lunch). Deni simo sada vrednosti niza d rekurzivno. Pretpostavimo da smo izra cunali vrednosti niza d do (k 1)-og elementa i zelimo izra cunati k -ti. Posle dodavanja novog elementa ak , za tra zenu optimalnu vrednost podniza (a1 , a2 , . . . , ak ) imamo dve mogu cnosti: element ak uklju cujemo u tra zenu sumu ili ne (elemente sa indeksima 1, . . . , k 2 koristimo u oba slu caja, jer na njih ne uti ce cinjenica da li je element k u sao u podniz ili ne). Ukoliko ga uklju cimo tada element na mestu k 1 ne sme u ci u sumu (po sto je susedan sa k -tim); u suprotnom element ak1 mo zemo uklju citi. Ovo formalnije zapisujemo kao: d[k ] = max{d[k 1], ak + d[k 2]}, za k 3 (1) Denisanjem baze d[1] = max{0, a1 } i d[2] = max{0, a1 , a2 } vrednosti niza d mo zemo izra cunati jednostavnom for ciklusom. Pri ra cunanju vrednosti d[n] preko formule (1), rekurzivnim pozivima bi mogli i ci u beskona cnost ukoliko neke od vrednosti niza d nemamo izra cunate bez rekurzije. U na sem slu caju, elementi sa indexima 1 i 2 se mogu inicijalizovati na gore opisan na cin. Dva uzastopna elementa niza d nam deni su bazu, zato sto vrednost elementa sa indeksom n zavisi samo od prethodna dva elementa. Npr, u slu caju da je d[k ] = max{d[k 1], d[k 3]} + 4 bazu moraju da cine prva tri elementa niza d. Napomena: Denisanje niza d je logi cka posledica gornje induktivne analize. Ispituju ci slu cajeve poslednjeg elementa niza dobili smo jednostavan uslov optimalne vrednosti. Algoritam C: Pseudo kod problema maksimalne sume nesusednih u nizu
Input: Niz a prirodnih brojeva du zine n Output: subsequence - podniz nesusednih elemenata sa najve com sumom
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22

if n = 1 then return subsequence = a; end d[1] = max{0, a1 }; d[1] = max{0, a1 , a2 }; for k 3 to n do if d[k 1] > d[k 2] + a[k ] then d[k ] = d[k 1]; else d[k ] = d[k 2] + a[k ]; end subsequence = ; currentIndex = n; while (currentIndex > 0) do if d[currentIndex] = d[currentIndex 1] then add a[currentIndex] to subsequence; currentIndex = currentIndex 2; else currentIndex = currentIndex 1; end end return subsequence;

Opisanim algoritmom mo zemo izra cunati maksimalnu sumu podniza nesusednih elemenata, ali cemo se zadr zati na rekonstrukciji samog podniza. U ovom konkretnom slu caju ne moramo pamtiti 3

dodatne informacije, po sto je rekurentna formula jednostavna. Za njegovu rekonstrukciju nam je potrebno da znamo da li je za vrednost d[k ] element na poziciji k u sao u podniz ili ne. Ukoliko bi element a[n] pripadao tra zenom podnizu, tada bi vrednost d[n] bila jednaka d[n 2] + a[n]. U slu caju da element sa indeksom n pripada, tada ispitujemo element sa indeksom n 2; u suprotnom element n ne pripada tra zenom podnizu, pa zato prelazimo na element a[n 1]. Treba napomenuti da opisanim postupkom dobijamo optimalni podniz u obrnutom porektu. Slo zenost opisanog algoritma je linearna, O(n) (ra cunanje niz d je linearna, dok je rekonstrukcija tra zenog podniza slo zenosti O(|subsequence|) = O(n)). Uklapanjem svih koraka, algoritam mo zemo opisati pseudokodom u Algoritmu C. Na primer, za dati niz a = {1, 2, 0, 8, 10, 3, 11}, niz d je d = {1, 1, 1, 9, 11, 12, 12}

Slika 1: Tra zeni podniz u primeru Problema 1 Napomena: Opisani algoritam se mo ze implementirati i rekurzivno. Parametar rekurzivne funkcije je index k i ona kao rezultat vra ca vrednost d[k ]. Kako bi izbegli ponovno ra cunanje istih stanja, markira cemo obid ena stanja i u slu caju da je stanje ve c ra cunato, vrati cemo odmah vrednost d[k ]. Op sti opis algoritma dat je pseudo kodom u Algoritmu D. Algoritam D: Op sti opis rekurzivne varijante DP-a
Input: stanje A Output: optimalna vrednost stanja A, zapam cena u globalnom nizu d
1 2 3 4 5 6

if stanje A ve c obidjedno then return d[A]; end inicijalizuj vrednost d[A] rekurzivno; markiraj stanje A kao obidjeno; return d[A];

Poznatiji problemi

U ovom odeljku cemo prodiskutovati neke poznatije predstavnike klase problema koje mo zemo re siti uz pomo c DP. U primeru iz prethodnog dela smo videli kako mo zemo DP primeniti na jednodimenzionalnom problem, gde nam je podproblem bio okarakterisan jednim parametrom. Problem 2 [Problem maksimalnog zbira u matrici] Data je matrica a dimenzije n m popunjena celim brojevima. Sa svakog polja u matrici dozvoljeno je pre ci samo na polje ispod ili na polje desno od tog polja (ukoliko postoje). Potrebno je izabrati put od gornjeg levog polja (polja sa koordinatama (1, 1)), do donjeg desnog polja (polja sa koordinatama (n, m)), tako da zbir brojeva u poljima preko kojih se ide, bude maksimalan. Kao sto se mo ze pretpostaviti, generisanje svih puteva i pam cenje onog puta koji ima najve ci zbir, nije dobra ideja. Broj mogu cih puteva raste eksponencijalno sa porastom dimenzija matrice m (preciznije, broj razli citih puteva je jednak n+ ). n Poku sajmo da razmi sljamo unazad: neka je P = {p1 = (1, 1), . . . , pn+m1 = (n, m)} tra zeni put sa maksimalnim zbirom. Kako se svakim potezom rastojanje do krajnjeg polja smanjuje za 1, znamo da je du zina tra zenog puta jednaka n + m 1. Tada svaki deo optimalnog puta P spaja polazno i zavr sno 4

polje tog dela puta na optimalan na cin. Ovu cinjenicu mo zemo jednostavno dokazati kontradikcijom: pretpostavimo da postoji optimalniji put koji spaja polja pa i pb od puta p = pa , pa+1 , . . . , pb . Ozna cimo taj put sa q . Tada dobijamo da je put p1 , p2 , . . . , pa1 , q, pb+1 , . . . , pn+m1 optimalniji od puta P , sto je nemogu ce. Na osnovu ove cinjenice se prosto name ce denicija podproblema: path[i][j ] = optimalan put od polja (1, 1) do polja (i, j ) d[i][j ] = suma elemenata na optimalnom putu od polja (1, 1) do polja (i, j )

Slika 2: Ukoliko je put a p b optimalan za stanja Start i End, tada je i put p optimalan za stanja A i B Iz gornjih denicija imamo da ce krajnji rezultat biti d[n][m], odnosno path[n][m]. Pitanje koje se sada postavlja jeste da li se d[i][j ] mo ze ra cunati rekurzivno? Do polja (i, j ) mo zemo do ci preko polja (i 1, j ) i (i, j 1) (pretpostavimo da polja postoje). Kako je svaki deo optimalnog puta optimalan, d[i][j ] deni semo kao: d[i][j ] = max{d[i 1][j ], d[i][j 1]} + a[i][j ], za i, j 2 a tada se put path[i][j ] dobija dodavanjem polja (i, j ) na onaj od puteva path[i 1][j ] ili path[i][j 1] koji daje ve ci zbir u gornjoj jedna cini. Bazu DP ce u ovom slu caju predstavljati elementi prve vrste i prve kolone matrice d po sto za njih ne va zi gornja jedna cina. Kako od polja (1, 1) do polja (1, j ) odnosno (i, 1) postoje jedinstveni putevi, popunjavanje matrice se mo ze jednostavno realizovati na slede ci na cin: d[1][1] = a[1][1], d[1][j ] = d[1][j 1] + a[1][j ], za j 2, d[i][1] = d[i 1][1] + a[i][1], za i 2, sto je jako sli cno rekurentnoj jedna cini, stim sto ovde nemamo biranje maksimuma iz dvoelementnog skupa jer elementi imaju samo jednog suseda. Kao i u prvom primeru, pri rekonstrukciji samog puta, nije potrebno pamtiti celokupnu matricu path. Tra zeni put se mo ze prona ci kretanjem od nazad i biranjem onog polja (gornjeg ili levog) koje nam donosi ve ci zbir. Ukoliko memorijsko ograni cenje to dozvoljava, mo zemo da pamtimo prethodno polje sa kojeg smo do sli, cime bismo izbegli specijalne slu cajeve koje nam skrivaju prva vrsta i kolona. Put ce opet biti u obrnutom redosledu pa se ili mora rotirati na kraju ili pamtiti u steku. Med utim, kako u ovom slu caju znamo du zinu puta (u prvom problemu nismo znali kolika je du zina tra zenog podniza) mo zemo odmah i sam niz popunjavati od nazad, pa ne cemo imati potrebe za njegovim rotiranjem. Napomena: Problem sa specijalnih slu cajeva prve vrste i kolone mo zemo re siti elegantnije. Naime, problem rekurentne fromule je taj sto navedena polja ne moraju uvek postojati. Ukoliko bi dodali jo s po jednu vrstu i kolonu sa indeksom 0 u matrici d i popunimo ih brojevima koji su sigurno manji od brojeva iz matrice, time obezbed ujemo da put forsirano ostane u prvobitnoj matrici. U ovom slu caju bazu DP ne bismo imali, tj. redovi 3, 4, . . . , 10 pseudo koda bi bila zamenjeni inicijalizacijom nulte vrste i kolone brojevima koji su manji od svih brojeva u matrici (koja su obi cno data kao ograni cenja samog problema). Na Slici 2 je prikazan rezultat algoritama na jednom primeru. Ovaj problem se mo ze sresti u vi se varijanti: 5

Algoritam E: Pseudo kod problema maksimalnog zbira u matrici


Input: Matrica a celih brojeva dimenzije n m Output: path - niz elemenata matrice koji predstavlja tra zeni put
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28

d[1][1] = a[1][1]; prior[1][1] = (0, 0); for j 2 to m do d[1][j ] = d[1][j 1] + a[1][j ]; prior[1][j ] = (1, j 1); end for i 2 to n do d[i][1] = d[i 1][1] + a[i][1]; prior[i][1] = (i 1, 1); end for i 2 to n do for j 2 to m do if d[i 1][j ] > d[i][j 1] then d[i][j ] = d[i 1][j ] + a[i][j ]; prior[i][j ] = (i 1, j ); else d[i][j ] = d[i][j 1] + a[i][j ]; prior[i][j ] = (i, j 1); end end end path = ; currentF ield = (n, m); while (currentF ield = (0, 0)) do add currentF ield in path; currentF ield = prior[currentF ield.i][currentF ield.j ]; end return path;

Slika 3: Primer problema maksimanog zbira u matrici

Prva varijanta se razlikuje u dodatnom uslovu: tra zeni put mora pro ci kroz polje (x, y ). Ovo je jedan od cestih uslova DP problema, kada (uz uslov optimalnosti) re senje mora pro ci kroz neka stanja. Re senje ovakvog problema se obi cno svodi na po cetni problem koji nezavisno pozivamo nad delom ulaza. Konkretno u na sem slu caju, tra zeni put ce biti unija optimalnih puteva p i q , gde je p put od polja (1, 1) do polja (x, y ), a put q od polja (x, y ) do polja (n, m). e ne samo u polja koja su desno i dole, ve c Druga varijanta dozvoljava da se iz jednog polja pred i u polje iznad. Naravno, ovde se mora dodati i uslov da se svako polje u putu obid e najvi se jednom (u suprotnom bi moglo do ci do beskona cnog puta). Ovaj problem je komplikovaniji od prethodnih i ne cemo ga ovde razmatrati. Pre nego sto pred emo na naredni problem, deni simo pojam podniza: Niz a je podniz niza b ukoliko se niz a mo ze dobiti izbacivanjem nekih elemenata niza b. Na primer, imamo da je {2, 1, 7, 7} podniza niza {5, 2, 1, 3, 7, 1, 7}, ali nije podniz od {2, 5, 7, 7, 1}. Problem 3 [Najdu zi zajedni cki podniz (NZP)] Data su dva niza a i b. Na ci niz najve ce mogu ce du zine koji je podniz i za a i za b. Problem najdu zeg zajedni ckog podniza (eng. Longest Common Subsequence) jako dobro demonstrira mo c DP. Na po cetku, veoma brzo mo zemo uo citi da se uklju civanjem bilo kakvih karakteristika problema ne mo ze izbe ci eksponencialna slo zenost, ukoliko problem ne posmatramo kroz podprobleme. Najlak se mo zemo baratati podnizovima koji su sastavljeni od po cetnih elemenata niza, pa zato matricu lcs deni semo kao: lcs[x][y ] = NZP nizova {a1 , . . . , ax } i {b1 , . . . , by }, za 1 x n, 1 y m gde su n i m du zine nizova a odnosno b. U nastavku cemo podniz {a1 , . . . , ax } niza a ozna cavati sa ax . Poku sajmo sada da izrazimo vezu med u elementima opisane matrice. Na po cetku, NZP za podnizove a1 i bk je {a1 } ukoliko bk sadr zi element a1 a1 ; ina ce je . Naravno, za sve elemente matrice va zi length(lcs[x][y ]) min{x, y }. Posmatrajmo sada podnizove ax i by . Za njihov NZP postoje dve mogu cnosti: element a[x] ulazi u NZP ili ne. Ukoliko ne ulazi, tada jednostavno imamo da je lcs[x][y ] = lcs[x 1][y ]. Pretpostavimo sada da a[x] ulazi u NZP tada podniz by mora sadr zati element a[x]. Neka se element a[x] nalazi na pozicijama 1 c1 < . . . < ck y u podnizu by . Kako element a[x] mora imati svog parnjaka u nizu by , imamo da je lcs[x][y ] = max{d[x 1][c1 1], . . . , d[x 1][ck 1]} + {ax }. Kako je length(lcs[x][y1 ]) length(lcs[x][y2 ]) za y1 y2 prethodnu formulu mo zemo napisati kao lcs[x][y ] = lcs[x 1][ck 1] + {ax } gde je ck index poslednjeg pojavljivanja elementa ax u podnizu by . Kada slo zimo prethodnu pri cu, lcs[x][y ] se ra cuna na slede ci na cin: lcs[x][y ] = max{lcs[x 1][y ], lcs[x 1][ck 1] + {ax }} (2)

Slika 4: Primer najdu zeg zajedni ckog podniza

Algoritam F: Pseudo kod problema NZP


Input: Dva niza a i b du zina n odnosno m Output: LCS - najdu zi zajedni cki podniz for j 0 to m do lenLCS [0][j ] = 0; end for i 0 to n do 5 lenLCS [i][0] = 0; 6 end
1 2 3 4 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30

for i 1 to n do for j 1 to m do if a[i] = b[j ] then lenLCS [i][j ] = lenLCS [i 1][j 1] + 1; else lenLCS [i][j ] = max{lenLCS [i][j 1], lenLCS [i 1][j ]}; end end end LCS = ; x = n; y = m ; while (x > 0 and y > 0) do if a[x] = b[y ] then add a[x] to LCS ; x = x 1; y = y 1 ; else if lenLCS [x][y 1] > lenLCS [x 1][y ] then y = y 1; else x = x 1; end end end return LCS ;

Poku sajmo da opi semo slo zenost gorenjeg algoritma. Kako jedini problem u formuli predstavlja pronala zenje samog indeksa ck , mo zemo napisati da je slo zenost O(n m F indCk ). Index ck mo zemo 2 pretra zivati linearno sto bi nas dovelo do slo zenosti O(nm ). Ostavimo sada formulu (2) sa strane i poku sajmo da pristupimo ra cunanju lcs[x][y ] na drugi na cin. bi bilo u Ukoliko bi elementi ax i by bili jednaki, tada va zi lcs[x][y ] = lcs[x 1][y 1] + {ax }. Sta slu caju da su oni razli citi? Kako se navedeni elementi nalaze na poslednjim pozicijama nizova ax i by , u slu caju da oba ulaze u NZP, tada bi morali biti jednaki, sto je suprotno pretpostavci. Dakle, u tom slu caju mo zemo tvrditi da je lcs[x][y ] = max{lcs[x][y 1], lcs[x 1][y ]}. Gornja relacija nam omogu cava da izra cunamo sve elemente lcs[x][y ] redom po vrstama ili po kolonama, znaju ci da je lcs[x][0] = lcs[0][y ] = . Naravno, nije potrebno pamtiti same podnizove. Dovoljno je pamtiti njihove du zine ozna ci cemo ih sa lenLCS [x][y ]. Rekonstukcija samog podniza se sli cno prethodnim problemima mo ze realizovati iz matrice lenLCS ili pam cenjem prethodnika. Slo zenost novog algoritma je O(nm). Ova dva algoritma nam demonstriraju jednu bitnu cinjenicu. Naime, nije uvek toliko o cigledno koju rekurzivnu vezu treba uo citi. Za istu deniciju podproblema mo zemo imati vi se veza, koje kao sto vidimo, ne moraju imati iste slo zenosti. Ovde cak imamo da je bolji algoritam i daleko jednostavniji za implementaciju. Napomena: Ukoliko bi se tra zila samo du zina NZPa, tada mo zemo da u stedimo memorijski prostor. Naime, umesto cele matrice lenLCS mo zemo da imamo samo dva niza, koji bi igrali ulogu vrste iz lenLCS koja se trenutno formira i prethodne vrste. Ovo mo zemo uraditi po sto nam izra cunavanje elementa lenLCS [x][y ] zavisi samo od elemenata u vrstama x i x 1. zi rastu ci podniz (NRP)] Data je niz a du zine n. Treba odrediti najdu zi podniz Problem 4 [Najdu ne obavezno uzastopnih elemenata datog niza, koji je rastu ci. Prikaza cemo tri razli cita pristupa re savanju problema najdu zeg rastu ceg podniza (eng. Longest Increasing Subsequence). U deniciji problema je navedeno da se tra zi rastu ci podniz, tako da cemo mi u daljem tekstu pod rastu cim, bez gubljenja op stosti, podrazumevati strogu nejednakost. Na primeru a = {1, 9, 3, 8, 11, 4, 5, 6, 4, 19, 7, 1, 7} mo zemo videti da je najdu zi rastu ci podniz du zine 6 i to {1, 3, 4, 5, 6, 7}. Najjednostavnije re senje jeste da svedemo ovaj problem na ve c poznati problem nala zenja najdu zeg zajedni ckog podniza. Konstrui semo niz b, koji predstavlja sortirani niz a u vremenu O(n log n), a zatim nad emo najdu zi zajedni cki podniz za nizove a i b u vremenu O(n2 ). Takod e, postoji pravolinijsko re senje dinami ckim programiranjem koje takod e radi u kvadratnoj slo zenosti. Iako su slo zenosti ekvivalentne, ovaj algoritam je znatno br zi u praksi. Neka je d[k ] du zina najdu zeg rastu ceg podniza niza a, sa ograni cenjem da je poslednji element upravo a[k ]. Globalni NRP se mora zavr siti na nekom elementu niza a, pa cemo kona cno re senje dobiti nala zenjem maksimuma u nizu d. Ostaje da rekurzivno izra cunamo elemente niza d. Kada ra cunamo d[k ], posmatramo skup svih indeksa Sk za koje va zi i < k i a[i] < a[k ]. Ako je skup Sk prazan, tada su svi elementi koji se nalaze pre a[k ] u nizu a ve ci od njega, sto dovodi do d[k ] = 1. Ina ce, ako maksimiziramo du zinu najdu zeg rastu ceg podniza u okviru skupa Sk , tada samo dodamo element a[k ] na kraj ovog niza. Zaklju cujemo da va zi slede ca formula: d[k ] = max{d[i] | i Sk } + 1 =
i<k,a[i]<a[k]

max

d[i] + 1.

Ukoliko je potrebno nala zenje jednog NRP (po sto tra zeni podzniz ne mora biti jedinstven), to mo zemo uraditi kori s cenjem pomo cnog niza p. Naime, p[k ] ce nam predstavljati indeks i, koji je maksimizirao gornji izraz pri ra cunanju d[k ]. Takod e, najdu zi rastu ci podniz se mo ze rekonstruisati i jednim prolaskom kroz niz od nazad. Sada cemo prikazati re senje u vremenskoj slo zenosti O(n log k ), gde je k du zina najdu zeg rastu ceg podniza. Deni simo Ai,j kao:

Algoritam G: Pseudo kod problema NRP


Input: Niz a du zine n Output: LIS - najdu zi rastu ci podniz niz a
1 2 3 4 5 6 7 8 9 10 11 12 13 14

for k 1 to n do max = 0; for i 1 to k 1 do if a[k ] > a[i] and d[i] > max then max = d[j ]; end end d[k ] = max + 1; end

max = 0; index = 0; for k 1 to n do if d[k ] > max then max = d[k ]; 15 index = k ; 16 end 17 end
18 19 20 21 22 23 24 25 26 27 28

LIS ; while d[index] > 1 do add a[index] to LIS ; i = index 1; while d[index] > d[i] + 1 do i = i 1; end index = i; end add a[index] to LIS ; return LIS ;

10

Ai,j

najmanji mogu ci poslednji element svih rastu cih nizova du zine j koriste ci elemente a[1], a[2], . . . , a[i]

Primetimo da za svako i, va zi Ai,1 < Ai,2 < . . . < Ai,j . Dakle, kada tra zimo najdu zi rastu ci podniz koji se zavr sava elementom a[i + 1] potrebno je da nad emo indeks j takav da je Ai,j < a[i + 1] Ai,j +1 . U tom slu caju ce tra zena du zina biti jednaka j +1 i Ai+1,j +1 ce biti jednako ai+1 dok ce ostali elementi niza Ai+1 ostati nepromenjeni. Zaklju cujemo da postoji najvi se jedna razlika izmed u nizova Ai i Ai+1 . Kako je niz Ai uvek sortiran i posle primene gornje operacije - mo zemo koristiti binarnu pretragu (eng. binary search). Algoritam H: Pseudo kod problema NRP
Input: Niz a du zine n Output: LIS - najdu zi rastu ci podniz
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31

max = 1; LIS [1] = 0; for i 1 to n do if a[LIS [max]] < a[i] then p[i] = LIS [max]; max = max + 1; LIS [max] = i; end else lef t = 0; right = max 1; while (lef t < right) do m = (lef t + right)/2; if a[LIS [m]] < a[i] then lef t = m + 1; else right = m; end end if a[i] < a[LIS [lef t]] then if lef t > 0 then p[i] = LIS [lef t 1]; end LIS [lef t] = i; end end end

i = LIS [max]; for k max to 1 do i = p[i]; LIS [k ] = i; 32 end 33 return LIS ;

11

Problem ranca

Problem ranca (eng. Knapsack problem) je jedan od najpoznatijih problema DP. Ovaj problem takod e ima nekoliko varijanti. Jedna od jednostavnijih varijanti problema ranca je naredni problem, koji ce nas lepo uvesti u su stinu osnovne formulacije problema. Problem 5 Dat je niz prirodnih brojeva a du zine n i prirodni broj S 105 . Prona ci podniz niza a cija je suma jednaka S ili ustanoviti da takav podniz ne postoji. Vidimo da u postavci problema postoji ograni cenje za broj S . Kao sto cemo uskoro videti, ovo nam je potrebno po sto cemo pratiti neka med ustanja kojih ce biti upravo S . Za po cetak poku sajmo da ustanovimo postojanje podniza, a potom cemo videti kako ga i prona ci. Niz a du zine n ima ta no 2n podnizova pa ispitivanje svih podnizova odmah odbacujemo kao neekasno re senje. Deni simo zato niz sum du zine S na slede ci na cin: sum[k ] = true, f alse, ukoliko postoji podniz sa sumom k ina ce

Niz sum cemo ra cunati rekurzivno (dodava cemo jedan po jedan element niza a i a zurirati vrednosti niza sum): Na po cetku sve elementa niza sum inicijalizujemo na f alse, osim sum[0] koji ce biti true. Ovo odgovara slu caju kada iz niza a nismo uzeli ni jedan element. Pretpostavimo da smo do sada dodali elemente a[1], . . . , a[k 1] (tj. podniz ak1 ) i zelimo da dodamo element sa indeksom k . Koje elemente niza sum treba promeniti? Ukoliko je postojao podniz niza ak1 koji je imao suma s, tada je taj isti podniz i podniz niza ak pa vrednost sum[k ] treba ostati nepromenjena i jednaka true. Med utim, dodavanjem novog elementa postoji i podniz cija je suma s + a[k ] koju treba postaviti na true (ukoliko je ona jednaka f alse i va zi s + a[k ] S ). Odgovor na pitanje da li postoji podniz sa sumom S na ci cemo u vrednosti elementa sum[S ]. Ukoliko nas zanima i sam podniz, pamti cemo za svaki element sum[k ] preko kog elementa niza a smo do sli. Ta cnije, uvek kada neki element niza sum postavimo na true, element iz druge stavke a[k ] pamtimo kao prethodnika. Kao prethodnika elementa sum[0] kao i sve ostale do koji nismo uspeli da dod emo, postavi cemo na 1. Na taj na cin, jednostavnom iteracijom po prethodnicima elementa sum[S ], sve dok taj prethodnik ne postane 1, dobijamo tra zeni podniz. Napomena: Lako mo zemo primetiti da navedeni podniz nije jedinstven. Ukoliko bi zeleli da rekonstrui semo sve podnizove, treba pamtiti sve prethodnike ili ih ra cunati pri samoj rekonstrukciji (k -ti element je prethodnik sa element sum[s] ukoliko je sum[s a[k ]] = true). Napomena: Posebno pa znju treba obratiti na korak 7 u Algoritmu I, gde smo niz sum obilazili od nazad. U suprotnom bi imali slu caj da svaki element niza mo zemo upotrebiti proizvoljan broj puta. Naime, ukoliko bi niz a bio sastavljen samo od jednog elementa, na s niz sum bio imao vrednost true na pozicijama 0, a[0], 2a[0], . . .. Razlog za ovo je jednostavan: sum[a[0]] cemo markirati preko sum[0]. Kasnijom iteracijom dolazimo na element sum[a[0]] koji je true zbog cega markiramo element sum[a[0] + a[0]] itd. Kao sto smo napomenuli, problem ranca ima nekoliko varijanti. Dajemo onu formulaciju po kojoj je problem i dobio ime. Problem 6 Provalnik sa rancem zapremine N upao je u prostoriju u kojoj se cuvaju vredni predmeti. U prostoriji ima ukupno M predmeta. Za svaki predmet poznata je njegova vrednost v [k ] i njegova zapremina z [k ], k [1, M ]. Sve navedene vrednosti su celobrojne. Provalnik zeli da napuni ranac najvrednijim sadr zajem. Potrebno je odrediti koje predmete treba staviti u ranac. 12

Algoritam I: Pseudo kod problema podniza zadate sume


Input: Niz a du zine n; suma S koju ispitujemo Output: subArray - podniz sa sumom S (prazan ukoliko takav ne postoji) for i 0 to S do sum[i] = f alse; 3 prior[i] = 1; 4 end 5 sum[0] = true;
1 2

for k 1 to n do for s S downTo 0 do if sum[s] and sum[s] + a[k ] S then sum[s + a[k ]] = true; prior[s + a[k ]] = k ; 11 end 12 end 13 end
6 7 8 9 10 14 15 16 17 18

subArray = ; if sum[S ] then currentSum = S ; while prior[currentSum] = 1 do add prior[currentSum] to subArray ; 19 currentSum = currentSum a[prior[currentSum]]; 20 end 21 end return subArray ;

22

Dakle, treba izabrati one predmete za koje je suma zapremina manja ili jednaka N , a cija je suma vrednosti maksimalna. Na po cetku prokomentari simo nekoliko karakteristika problema: Ranac koji je optimalno popunjen, ne mora biti popunjen do vrha (u nekim slu cajevima to i ne ce biti ni mogu ce). Na primer, posmatrajmo slu caj u kome je N = 7 a v = {3, 4, 8}, z = {3, 4, 5}. Ovde je optimalno re senje uzeti samo poslednji predmet cime bi vrednost ranca bila 8, dok ranac ne bi bio u potpunosti popunjen. Najvredniji predmet ne mora u ci re senje: ideja da predmete treba sortirati po vrednosti po jedinici zapremine, tj. po v [k ]/z [k ] nije korektna. Ovaj pristup (grabljivi metod) ne daje uvek optimalno re senje, sto pokazuje primer: N = 7 i v = {3, 4, 6}, z = {3, 4, 5}. Ovde bi grabljivim algoritmom kao re senje uzeli 3. predmet, dok se optimalno re senje predstavljaju predmeti 1 i 2. Iz ove diskusije se vidi da problem nije jednostavan i da se do re senja ne mo ze do ci direktno. Analiziraju ci problem, mo zemo primetiti slede ce: ako je pri optimalnom popunjavanju ranca poslednji izabrani predmet k , onda preostali predmeti predstavljaju optimalno popunjavanje ranca zapremine N z [k ]. Ova konstatacija se lako dokazuje svod enjem na kontradikciju (kao i kod ve cine obrad enih problema). Prema tome, optimalno popunjavanje ranca sadr zi optimalno popunjavanje manjeg ranca, sto nas navodi na DP. Deni simo niz d[k ] za k [1, N ] kao: d[k ] = maksimalna vrednost ranca zapremine k pri cemu je ranac popunjen do vrha Optimalna vrednost ranca zapremine N se nalazi u nekom od elemenata d[k ] za k [1, N ]. Iz gornjeg razmatranja vidimo da se ra cunanje vrednosti d[m] mo ze svesti na ra cunanje elementa d[m z [k ]] za neki predmet k . Sli cno kao i kod prethodnog problema, niz d mo zemo ra cunati dodavanjem jednog po jednog predmeta. Na po cetku imamo slu caj praznog ranca i d[0] = 0 kao bazu. Kako se tra zi maksimalna vrednost ranca, mo zemo sve vrednosti niza d, osim pozicije 0, postaviti na (na kraju algoritma ukoliko je 13

d[k ] = to ce zna citi da datim predmetima ne mo zemo popuniti u potpunosti ranac zapremine k ). Pretpostavimo sada da smo dodali prvih k 1 predmeta i zelimo da dodamo i k -ti predmet. Pitamo se sta bi bilo da ranac sadr zi predmet k . Ukoliko bi sa njim ranac imao zapreminu S N tada bi ranac zapremine S z [k ] bio popunjen nekim podskupom prvih k 1 predmeta. Zato cemo svaki element d[s] = poku sati da pro sirimo za novi predmet. Dakle, ispitujemo da li je d[s + z [k ]] < d[s] + v [k ] i ukoliko jeste menjamo vrednost d[s + z [k ]] na optimalniju vrednost za ovu zapreminu d[s] + v [k ]. Da bi rekonstruisali sam niz predmeta koje cemo stavljati u ranac, za svaku vrednost d[k ] cemo pamtiti indeks poslednjeg dodatog predmeta (u nizu prior). Pseudo kod gore opisanog algoritma je prikazan u Algoritmu J. Algoritam J: Pseudo kod problema ranca
Input: Nizovi z i v du zine M ; zapremina ranca N Output: knapsack - niz optimalnih predmeta
1 2

for i 1 to S do d[i] = ; 3 prior[i] = 1; 4 end 5 d[0] = 0;

for k 1 to M do for i N z [k ] downTo 0 do if d[i] = and d[i + z [k ]] < d[i] + v [k ] then d[i + z [k ]] = d[i] + v [k ]; prior[i + z [k ]] = k ; 11 end 12 end 13 end
6 7 8 9 10 14 15 16 17 18

knapsack = ; index = max{i|i [0, N ] and d[i] = }; while prior[index] = 1 do currentItem = prior[index]; add currentItem to knapsack ; 19 index = prior[index z [currentItem]]; 20 end return knapsack ;

21

Razni zadaci

Ovde cemo izneti nekoliko zadataka koji se rade metodom dinami ckog programiranja. Re senja zadataka nisu obrad ena do detalja sa pseudokodom kao u prethodnim, ali je opisan kompletan algoritam. Ukoliko ste prethodne probleme razumeli, onda ne ce biti problema oko implementacije algoritama u omiljenom programskom jeziku. Zadaci su birani tako da svaki zadatak krije po neku novu metodu DP koja se mo ze koristiti u siroj klasi problema. Zadatak 5.1 (Srbija, Okru zno takmi cenje, 2000) Data je binarna matrica dimenzije n n, n 1000. Na ci dimenziju najve ce kvadratne podmatrice koja je sastavljena samo od nula. Re senje: Svaku kvadratnu podmatricu mo zemo denisati njenom veli cinom i jednim temenom, npr. donjim desnim. Poku sajmo da za svako polje matrice izra cunamo najve cu dimenziju podmatrice sastavljene samo od nula, tako da je dato polje upravo donji desni desni ugao. Ozna cimo tra zenu veli cinu sa d[x][y ]. Ukoliko bi d[x][y ] bilo jednako k , tada bi d[x 1][y ] moralo biti najmanje k 1, ba s kao i d[x][y 1]. Med utim ovo nije i dovoljan uslov, jer nam on ni sta ne govori o vrednosti u gornjem levom polju na se 14

Slika 5: Primer najve ce kvadratne podmatrice ciji su elementi samo 0 podmatrice dimenzije k . Taj uslov mo zemo proveriti preko d[x 1][y 1] k 1. Dakle, dobijamo d[x][y ] = 0, 1 + min{d[x 1][y ], d[x][y 1], d[x 1][y 1]}, ukoliko je matrix[x][y ] = 1 ukoliko je matrix[x][y ] = 0

gde naravno moramo paziti da navedeni indeksi pripadaju matrici. Na po cetku mo zemo izra cunati vrednosti u prvoj vrsti i koloni ili dodatni ve sta cke 0-te vrste i kolone. Ukoliko elemente matrice d ra cunamo kretanjem po vrstama sa leva na desno u trenutku ra cunanja elementa na poziciji (x, y ) potrebne vrednosti sa desne strane jednakosti ce biti ve c izra cunate. Zadatak 5.2 (TopCoder, SRM 255) Dati su brojevi 0 M < N 1.000.000. Odrediti najmanji broj sastavljen samo od neparnih cifara, koji pri deljenju sa N daje ostatak M . Ukoliko tra zeni broj ne postoji, stampati 1. Re senje: Kako konstruisati sve brojeve sastavljene od neparnih cifara? Postoji ta cno pet takvih jednocifrenih brojeva: 1, 3, 5, 7 i 9. Da bi dobili brojeve sa L neparnih cifara, dovoljno je pomno ziti svaki od (L 1)cifrenih brojeva sastavljenih od neparnih cifara, sa 10 i dodati svaku od neparnih cifara. Za re senje ce nam biti potreban jedan red q . Na po cetku ubacimo sve jednocifrene neparne brojeve u q . Zatim dodajemo sve neparnocifrene brojeve koji su dobijeni od 1, zatim sve neparnocifrene brojeve dobijene od 3 i tako dalje. Time cemo konstruisati sve neparnocifrene brojeve u rastu cem redosledu. Naravno, sve brojeve uzimamo po modulu N . Nema smisla imati dva broja sa jednakim ostatkom u nizu q , po sto ce oni generisati iste neparnocifrene brojeve. Zato koristimo niz d du zine N . Naime, d[i] predstavlja najmanji broj koji pri deljenju sa N daje ostatak i. Na po cetku, inicijalizujemo elemente niza d na 1. Mo zemo primetiti da ne moramo pamtiti cele brojeve (po sto mogu biti sastavljeni od mnogo cifara), ve c je dovoljno pamtiti poslednju cifru i prethodnika. Memorijska i vremenska slo zenost ovog algoritma je O(N ). Zadatak 5.3 (Srbija, Republi cko takmi cenje 2003) Dat je niz razli citih prirodnih brojeva du zine n. Nad nizom mo zete izvr savati dve operacije: proizvoljan element iz niza prebacite na njegov po cetak ili na njegov kraj. Odrediti minimalni broj operacija, tako da rezultuju ci niz bude rastu ci. Re senje: Ozna cimo dati niz sa a i pretpostavimo da smo pri simulaciji sortiranja pomerili elemente sa indeksima 1 x1 < . . . < xk n. Elemente koje nismo premestili zadr zali su svoj poredak kao i na po cetku. Kako na kraju treba dobiti sortirani niz, poredak nepreme stanih elemenata mora biti sortiran. Ova cinjenica nas navodi na to da treba prona ci najdu zi rastu ci podniz niza. Med utim, primetimo da se nijedan novi element ne mo ze ubaciti izmed u neka dva elementa koja nismo preme stali. Zato nalazimo najdu zi rastu ci podniz niza a uzastopnih elemenata (ne po indeksima ve c po vrednostima).

15

Slika 6: Primer sortiranja u Zadatku 5.2 Na po cetku, radi lak se manipulacije, mo zemo elemente niza preslikati u permutaciju brojeva od 1 do n. Niz d deni simo kao: d[n] = nadu zi rastu ci podniz elemenata sa indeksima iz segmenta [1, n] koji se zavr sava ntim elementom Niz d mo zemo ra cunati linearno, za razliku od najdu zeg rastu ceg podniza, jer ovde znamo koji element jedini mo ze da bude prethodnik (prethodnik za d[k ] je element koji ima vrednost a[k ] 1). Zadatak 5.4 (ACM SPOJ, PERMUT1) Data su dva prirodna broja n 1000 i k 10000. Na ci broj permutacija brojeva od 1 do n koji imaju ta cno k inverzija. Broj inverzija u permutaciji (p1 , p2 , . . . , pn ) je broj parova (i, j ) takvih da je pi > pj za 1 i < j n. Re senje: Stanje cemo opisati sa dva parametra: du zinom permutacije i brojem inverzija. Dakle, ozna cimo sa d[i][j ] = broj permutacija du zine i sa j inverzija Posmatrajmo jedinicu u tim permutacijama i njenu ulogu u broju inverzija. Ukoliko se ona nalazi na prvom mestu, onda ona ne u cestvuje ni u jednoj inverziji, pa tih permutacija ima d[i 1][j ] (jer je svejedno da li gledamo permutacije brojeva (1, 2, . . . , n 1) ili (2, 3, . . . , n)). Ako se jedinica nalazi na drugom mestu, tada permutacija sa j inverzija ima d[i 1][j 1]. Na ovaj na cin dolazimo do rekurentne formule:
n1

d[n][k ] =
i=0

d[n 1, k i]

Poku sajmo da navedena polja matrice d ra cunamo na optimalniji na cin. d[n][k ] = d[n][k 1] + d[n 1][k ] d[n 1][k n] Gornju relaciju nije te sko primetiti: ukoliko ispi sete sume za elemente d[n][k ] i d[n][k 1] vide cete da su one jako sli cne (ta cnije razlikuju se samo u dva sabiraka). Ovo dodatno smanjuje kako vremensku, tako i memorijsku slo zenost. Elemente matrice d ra cunamo u O(1), dakle vremenska slo zenost algoritma je O(nk ) dok je memorijska O(n), jer pamtimo samo poslednja dva reda matrice. Za po cetne vrednosti je dovoljno uzeti d[i][0] = 1 i d[0][j ] = 0. Napomenimo da treba voditi ra cuna o tome da li je broj inverzija k ve ci od broja ca i i broja elemenata n. Zadatak 5.5 (Hrvatska, Izborno 2001) Dat je niz d realnih brojeva du zine n 1000, koji predstavljaju udaljenost no cnih svetiljki od po cetka ulice. Za svaku od svetiljki je data i njena potro snja u jedinici vremena kada je upaljena. Perica se na po cetku nalazi na rastojanju start od po cetka ulice i zeli da pogasi sve svetiljke u ulici. On se kre ce brzinom od jednog metra u jedinici vremena. Kolika je minimalna potro snja svetiljki koje one proizvedu - dok ih Perica sve ne pogasi?

16

Re senje: Ozna cimo potro snju k -te sijalice sa w[k ]. Na po cetku radi lak seg ra cunanja sortirajmo sijalice po rastojanjima i transformi simo koordinate tako da se Perica nalazi na mestu sa koordinatom 0. Ubacimo i jednu ve sta cku sijalicu na koordinati 0. Deni simo slede ce oznake: L[x][y ] = D[x][y ] = T [x][y ] = T [x][y ] =
c

minimalna potro snja potrebna da se pogase sijalice sa indeksima x, x + 1, . . . , y i da se na kraju Perica nalazi kod sijalice x minimalna potro snja potrebna da se pogase sijalice sa indeksima x, x + 1, . . . , y i da se na kraju Perica nalazi kod sijalice y ukupna snaga koju tro se sijalice sa indeksima x, x + 1, . . . , y ukupna snaga koju tro se sijalice sa indeksima 1, . . . , x 1, y + 1, . . . , n

Elementi pomo cnih matrice T i T c ce nam biti potrebne za ra cunanje glavnih matrica L i D u kojima se zadr zi i krajnje re senje min{L[1][n], D[1][n]}. Razlog za tako denisane veze jeste cinjenica da ukoliko Perica pogasi sijalice a i b tada ce pogasiti i sijalice sa indeksima izmed u a i b. Pogledajmo prvo kako mo zemo elegantno izra cunati matricu T , po sto cemo sli cnu ideju kasnije koristiti za matrice D i L. Pomo cu jednakosti T [x][y ] = w[x] + T [x + 1][y ], ra cunanje neke vrednosti za segment [x, y ] dijamatra y x mo zemo da svedemo na ra cunanje segmenta [x + 1, y ] koji je dijamatra y x 1. Ukoliko bi elemente matrice T ra cunali na takav na cin da su u trenutku ra cunanja polja dijametra k , elementi sa manjim dijametrima inicijalizovani, gornju jednakost bi mogli implementirati i bez rekurzije. Ideja je da se matrica T popunjava dijagonalno. Algoritam K: Pseudo kod ra cunanja matrice T iz zadatka 5.4
Input: Niz potro snja sijalica w du zine n Output: matrica T for k 1 to n do T [k ][k ] = w[k ]; end for diameter 2 to n 1 do for x 1 to n diameter do y = x + diameter 1; 7 T [x][y ] = w[x] + T [x + 1][y ]; 8 end 9 end
1 2 3 4 5 6 10

return T ;
n k=1 w [k ].

Elemente matrice T c ra cunamo kao T c [x][y ] = S T [x][y ] gde je S = denisati rekurentne veze za matrice L i D. L[x][y ] = min

Sada mo zemo

L[x + 1][y ] + T c [x + 1][y ] (d[x + 1] d[x]), D[x + 1][y ] + T c [x + 1][y ] (d[y ] d[x]) D[x][y 1] + T c [x][y 1] (d[y ] d[y 1]), L[x][y 1] + T c [x][y 1] (d[y ] d[x])

D[x][y ] = min

Objasnimo rekurentnu jedna cinu za L[x][y ], po sto se veza za matricu D dobija analogno. Naime, da bi Perica pogasio sijalice iz segmenta [x, y ] na kraju mora biti ili kod sijalice x ili kod sijalice y . Kako bi ugasio sijalice [x, y ] mora pre toga ugasiti sijalice [x 1, y ]. Za njihovo ga senje postoje dva slu caja: da se nalazi u x 1 ili y , sto ujedno i predstavljaju gornje slu cajeve za ra cunanje elementa L[x][y ].

17

Reference
[1] Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest and Cliord Stein, Introduction to Algorithms, The MIT Press, 2001 [2] Udi Manber, Introduction to Algorithms, Addison-Wesley, Boston, 1989 [3] Robert Sedgewick, Algorithms, Addison-Wesley, 1984 [4] Donald E. Knuth, The Art of Computer Programming Volume 1,2,3, Addison-Wesley, 1973 [5] Milan Vugdelija, Dinami cko programiranje, Beograd, 1999 [6] http://www.topcoder.com/tc/ [7] http://www.uwp.edu/sws/usaco/ [8] http://www.spoj.pl/ [9] http://acm.timus.ru/ [10] http://www.z-trening.com/ [11] http://acm.uva.es/problemset/ [12] http://www.dms.org.yu/

18

You might also like