diff --git a/07-rekurze/fib.py b/07-rekurze/fib.py
new file mode 100755
index 0000000000000000000000000000000000000000..71d3597eeef2401be5b3739726c33e31fdc99842
--- /dev/null
+++ b/07-rekurze/fib.py
@@ -0,0 +1,28 @@
+#!/usr/bin/python3
+# Různé způsoby výpočtu Fibonacciho čísel
+
+### Čistá rekurzivní verze, exponenciálně pomalá
+
+def fib(n):
+    if n < 2:
+        return n
+    else:
+        return fib(n-1) + fib(n-2)
+
+### Rekurze s pamětí na už spočítané výsledky, složitost O(n)
+
+pamet = { 0: 0, 1: 1 }
+
+def fib1(n):
+    if n not in pamet:
+        pamet[n] = fib(n-1) + fib(n-2)
+    return pamet[n]
+
+### Iterativní řešení
+
+def fib2(n):
+    p = [0] * (n+1)
+    p[1] = 1
+    for i in range(2, n+1):
+        p[i] = p[i-1] + p[i-2]
+    return p[n]
diff --git a/07-rekurze/gen-01.py b/07-rekurze/gen-01.py
new file mode 100755
index 0000000000000000000000000000000000000000..5a7d287b7e8ddf100ff5862f28eaae53bd83a198
--- /dev/null
+++ b/07-rekurze/gen-01.py
@@ -0,0 +1,44 @@
+#!/usr/bin/python3
+# Generování všech posloupností 0 a 1 délky n
+# Posloupnosti vypisujeme v lexikografickém pořadí
+
+### První řešení: rekurzivní funkce, která vygeneruje všechny posloupnosti
+### začínající zadaným prefixem. Parametr "p" je prefix, "n" říká, kolik ještě
+### potřebujeme přidat prvků.
+
+def gen01(n, p=[]):
+    if n == 0:
+        print("".join(map(str, p)))
+    else:
+        gen01(n-1, p + [0])
+        gen01(n-1, p + [1])
+
+### V předchozím řešení se v každém volání funkce kopíruje seznam až n prvků,
+### takže i vnitřní vrcholy stromu rekurze mají linearní složitost. Toho se můžeme
+### zbavit, když prefix místo v argumentu funkce předáváme v proměnné sdílené
+### všemi instancemi funkce.
+
+def gen01b(n):
+
+    def g(n):
+        if n == 0:
+            print("".join(map(str, p)))
+        else:
+            for i in [0, 1]:
+                p.append(i)
+                g(n-1)
+                p.pop()
+
+    p = []
+    g(n)
+
+### Funkci gen01 můžeme také upravit, aby místo vygenerování všech posloupností
+### jenom spočítala, kolik jich je. Na prefixu nezáleží, tak ho nemusíme předávat.
+### Díky tomu stačí jen jedno rekurzivní volání a výsledek znásobit dvěma,
+### takže funkce má celkově složitost O(n).
+
+def count01(n):
+    if n == 0:
+        return 1
+    else:
+        return 2 * count01(n-1)
diff --git a/07-rekurze/gen-k1.py b/07-rekurze/gen-k1.py
new file mode 100755
index 0000000000000000000000000000000000000000..61e7de65e939842447689a350834ea94552c2321
--- /dev/null
+++ b/07-rekurze/gen-k1.py
@@ -0,0 +1,54 @@
+#!/usr/bin/python3
+# Generování všech posloupností 0 a 1 délky n, ve kterých je právě k jedniček
+# Posloupnosti vypisujeme v lexikografickém pořadí
+
+### Rekurzivní řešení: generujeme všechny posloupnosti délky s prefixem p,
+### do kterých potřebujeme přidat n cifer, z nichž k jsou jedničky.
+
+def genk1(n, k, p=[]):
+    if n == 0:
+        print("".join(map(str, p)))
+    else:
+        # 0 můžeme přidat, pokud zbude dost pozic na to, aby se do nich
+        # vešly všechny zbývající 1.
+        if k < n:
+            genk1(n-1, k, p + [0])
+
+        # 1 můžeme přidat, pokud jsme ještě všechny nespotřebovali.
+        if k > 0:
+            genk1(n-1, k-1, p + [1])
+
+### A opět můžeme podobným způsobem počítat, kolik takových posloupností existuje:
+
+def countk1(n, k):
+    if n == 0:
+        return 1
+    else:
+        result = 0
+        if k < n:
+            result += countk1(n-1, k)
+        if k > 0:
+            result += countk1(n-1, k-1)
+        return result
+
+### Počítačí funkce je ovšem pomalá: výsledek je kombinační číslo (poznáváte
+### v naší funkci součtový vzorec z Pascalova trojúhelníku?) a nasčítáme ho
+### postupně z jedniček. Přitom "n nad n/2" je řádově 2^n / √n. Stejně jako
+### u příkladu s Fibonacciho čísly si můžeme mezivýsledky pamatovat a tím
+### výpočet zrychlit na O(n^2). Mimochodem, uměli byste to rychleji, aniž
+### byste potřebovali mezivýsledky řádově větší než výsledek?
+
+mem = {}        # Slovník, kde klíče jsou tuply (n,k)
+
+def countk1b(n, k):
+    if (n,k) not in mem:
+        if n == 0:
+            result = 1
+        else:
+            result = 0
+            if k < n:
+                result += countk1b(n-1, k)
+            if k > 0:
+                result += countk1b(n-1, k-1)
+        mem[(n,k)] = result
+    return mem[(n,k)]