# 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í