# Dynamické programování - trochu jako D&C, ale jde zdola nahoru, každý podproblém řeší jen 1x - v tabulce uložena nejlepší dílčí řešení, kombinují se pro získání větších řešení - **dynamika** - pro problémy, kde je čas výpočtu a pořadí operací důležité - tak trochu kombinace brutální síly a žravé strategie (greedy) - minimalizace úsilí důsledným využíváním dílčích výsledků Příklad: $n$-té Fibbonaciho číslo - DP spočte - $F(0), F(1), F(2) = F(1) + F(0), \dots F(n) = F(n-1) + F(n-2)$ - $\implies O(n)$ - D&C spočte - $F(n), F(n-1), F(n-2), F(n-2), \dots$ - $\implies O(2^n)$ - některé dílčí výsledky se počítají zbytečně víckrát Příklady - nejdelší rostoucí posloupnost - problém dělení **Použitelnost DP** - problém výhodný pro DP: - princip optimality - podstatný je stav, ne způsob, jakým se do něj došlo - důležitá je cena operací, ne samotné operace - většina kombinatorických problémů - největší omezení - počet dílčích řešení, která je nutno sledovat - potřebujeme zastavovací místa, implicitní pořadí prvků - pokud není splněno, máme exponenciální počet možných dílčích řešení a nedostatek paměti **Typický problém pro DP** - dekomponovatelný do posloupnosti rozhodnutí, přijatých v různých etapách - každá etapa má určitý počet možných stavů - rozhodnutí nás převádí ze stavu v jedné etapě do stavu v druhé etapě - nejlepší posloupnost rozhodnutí v určité etapě je nezávislá na rozhodnutích v dřívějších etapách - cena přechodu mezi stavy v různých etapách je jasně definována - existuje rekurentní vztah pro výběr nejlepšího rozhodnutí