# ADS úlohy E - podobne
Nejprve je potřeba si rozmyslet, zda přidání dalšího prvku na konec posloupnosti ovlivní dosavadní posloupnosti:
Budu-li postupovat v posloupnosti od konce do začátku, mohu najít první číslo, jehož rozdíl s posledním číslem přesáhne toleranci ($k$). Pro další výpočty pak mi stačí uvažovat pouze úsek napravo od tohoto čísla. Zároveň je však potřeba si uvědomit, že i předposlední číslo již vyhradilo jakýsi úsek, ve kterém má smysl zkoumat podposloupnosti - budu se tak zabývat kratším z těchto úseků.
Nyní vezmu následující situaci: mám posloupnost $P$ s finálním prvkem $P_{n+1}$, pro nějž je zarážka na pozici $s_1$.
Jelikož se jedná o první zarážku, celá posloupnost od $0$ do $n$ je platná a tuto posloupnost nelze rozšířit zleva ani zprava. Označím tak $t_0=n$ a $s_0=0$, což znamená, že podposloupnost má délku $t_0 - s_0$.
Dále, mezi $P_{s+1}$ a $P_{n+1}$ nevznikla žádná zarážka, a tak mohu postup opakovat (jako bych opět počítal od nuly), dokud nevznikne další zarážka.
## Algoritmus (1):
Vstup: posloupnost $P$ s prvky od $0$ do $n$, hranice $k$.
1. $s_0=0$
2. $x=0$
4. Pro $u \in \{1 \dots n\}$:
1. Pro $v \in \{u-1 \dots s_x\}:$
2. Je-li $|P_u-P_v|>k$:
1. $t_x=u$
2. $x=x+1$
3. $s_x=v+1$
5. Ukonči cyklus
5. $t_x=n$
6. Najdi takové $s_x$, aby rozdíl $t_x-s_x$ byl co největší.
7. Výstup: Nejdelší posloupnost prvků $P_{s_x} \dots P_{t_x-1}$.
## Zdůvodnění:
Algoritmus vlastně rozkouskuje interval na souvislé podposloupnosti, které již nejdou rozšířit. (nemusí být nutně disjunktní). Vybrat tu nejdelší nepředstavuje žádný problém.
Levá zarážka $s_x$ (inkluzivní) vzniká tehdy, kdy zkoumané číslo $P_u$ nelze odečíst od čísla před touto zarážkou - proto nelze posloupnost, ve které se nachází $P_u$, rozšířit směrem doleva. Ze stejného důvodu se $P_{u}$ stává pravou zarážkou (již nepatřící do ní) - $t_x$ pro předchozí podposloupnost.
## Složitost(1):
Pokud chci pouze nejdelší podposloupnost, pak mi stačí uchovávat si v paměti maximum a momentální podposloupnost, takže paměťové nároky budou konstantní. V opačném případě budu potřebovat lineární paměť na všechny zarážky.
Časová složitost závisí na tom, kolik budu mít zarážek. Nemám-li žádné, pak celá posloupnost je "v toleranci" a složitost tak bude kvadratická.
## Optimalizace:
Nevznikne-li pro daný prvek $P_u$ zarážka, pak pro následující prvky budu porovnávat rozdíl přes naprosto stejné prvky. Toto bych si mohl ušetřit tím, že pro daný interval zjistím maximum a minimum a budu porovnávat jen rozdíl mezi maximem a minimem.
## Algoritmus(2):
Vstup: posloupnost $P$ s prvky od $0$ do $n$, hranice $k$.
1. $s_0=0$
2. $x=0$
3. $maxim=- \infty, minim=+ \infty$
4. $d=0$
5. $z=true$
6. Pro $u \in \{1 \dots n\}$:
1. Je-li $z=false$ a je-li $|P_u-maxim|\leq k$ a $|P_u-minim|\leq k$:
2. $maxim=Max(P_u,maxim)$
3. $minim=Min(P_u,minim)$
4. Pokračuj dále
2. Jinak (je potřeba vytvořit zarážku):
3. $z=false$
4. Pro $v \in \{u-1 \dots s_x\}:$
5. Je-li $|P_u-P_v|>k$:
1. $z=true$
2. $t_x=u$
3. $x=x+1$
4. $s_x=v+1$
5. $maxim=Max(P_{s_x} \dots P_u)$
6. $minim = Min(P_{s_x} \dots P_u$
7. Ukonči cyklus
7. $t_x=n$
8. Najdi takové $s_x$, aby rozdíl $t_x-s_x$ byl co největší.
9. Výstup: Nejdelší posloupnost prvků $P_{s_x} \dots P_{t_x-1}$.
## Složitost (2):
Paměťová složitost výše popsaného je $O(n)$, pokud již zaznamenávám maximum, pak $O(1)$.
Co se týče časové složitosti: Pouhé rozšíření posloupnosti (nový prvek se vleze do tolerance maxima i minima) má složitost O(1). V případě, že je potřeba posloupnost uzavřít, může být opět potřeba prohledat $O(n)$ prvků, levá zarážka se posune o jeden prvek, a tak složitost v nejhorším případě by stále byla $O(n^2)$.