diff --git a/README.md b/README.md
index 46f8b24..c9f04c6 100644
--- a/README.md
+++ b/README.md
@@ -42,8 +42,8 @@
 | 01     | Sorting algorithms     | [Slides][Slides_W01] | [Test][WarmUp_test_W01] | [Contest][ContestID_W01] | 07.05.2024 09:00 UTC+7 |
 | 02     | Binary search          | [Slides][Slides_W02] | [Test][WarmUp_test_W02] | [Contest][ContestID_W02] | 08.05.2024 09:00 UTC+7 |
 | 03     | Basic Data sturctures  | [Slides][Slides_W03] | [Test][WarmUp_test_W03] | [Contest][ContestID_W03] | 09.05.2024 09:00 UTC+7 |
-<!---
 | 04     | Dynamic programming    | [Slides][Slides_W04] | [Test][WarmUp_test_W04] | [Contest][ContestID_W04] | 10.05.2024 09:00 UTC+7 |
+<!---
 | 05     | Knapsack problem       | [Slides][Slides_W05] | [Test][WarmUp_test_W05] | [Contest][ContestID_W05] | 13.05.2024 09:00 UTC+7 |
 | 06     | KMP & Heap             | [Slides][Slides_W06] | [Test][WarmUp_test_W06] | [Contest][ContestID_W06] | 14.05.2024 09:00 UTC+7 |
 | 07     | DFS & BFS              | [Slides][Slides_W07] | [Test][WarmUp_test_W07] | [Contest][ContestID_W07] | 15.05.2024 09:00 UTC+7 |
diff --git a/week04_dynamic_programming/HS.BKK.2024.Algo.Class04.pdf b/week04_dynamic_programming/HS.BKK.2024.Algo.Class04.pdf
new file mode 100644
index 0000000..6ac7792
Binary files /dev/null and b/week04_dynamic_programming/HS.BKK.2024.Algo.Class04.pdf differ
diff --git a/week04_dynamic_programming/fibonacci.py b/week04_dynamic_programming/fibonacci.py
new file mode 100644
index 0000000..b05b53f
--- /dev/null
+++ b/week04_dynamic_programming/fibonacci.py
@@ -0,0 +1,54 @@
+from time import time
+from matplotlib import pyplot as plt
+
+
+def fib_recursive(n):
+    if n < 2:
+        return n
+    return (fib_recursive(n - 1) + fib_recursive(n - 2)) % 10**9
+
+
+fibonacci_mem = {}
+
+
+def fib_mem(n):
+    if n < 2:
+        return n
+    if n not in fibonacci_mem:
+        fibonacci_mem[n] = (fib_mem(n - 1) + fib_mem(n - 2)) % 10 ** 9
+    return fibonacci_mem[n]
+
+
+def fib_tab(n):
+    res = [0] * max((n + 1), 2)
+    res[0] = 0
+    res[1] = 1
+    for i in range(2, n + 1):
+        res[i] = (res[i - 1] + res[i - 2]) % 10**9
+    return res[n]
+
+
+if __name__ == '__main__':
+    times = []
+    N_max = 35
+    step = 1
+    for i in range(1, N_max, step):
+        t = time()
+
+        # naive solution:
+        x = fib_recursive(i)
+
+        # memoization:
+        # cache is resettet to calculate correct time for each i
+        # otherwise it will take old values from cache:
+        # fibonacci_mem = {}
+        # x = fib_mem(i)
+
+        # tabulation:
+        # x = fib_tab(i)
+
+        times.append(time() - t)
+        print(f'N={i}: {times[-1]:.8f} sec.')
+
+    plt.plot(times)
+    plt.show()
diff --git a/week04_dynamic_programming/lis_N2.py b/week04_dynamic_programming/lis_N2.py
new file mode 100644
index 0000000..c63443f
--- /dev/null
+++ b/week04_dynamic_programming/lis_N2.py
@@ -0,0 +1,19 @@
+def lis_n2(x):
+    N = len(x)
+    d = [0] * N
+    d[0] = 1
+    for i in range(1, N):
+        # don't need to find j
+        # Need just to calculate maxd:
+        max_d = 0
+        for j in range(i):
+            if x[j] < x[i] and d[j] > max_d:
+                max_d = d[j]
+        d[i] = max_d + 1
+    return max(d)
+
+
+if __name__ == '__main__':
+    N = int(input())
+    x = list(map(int, input().split()))
+    print(lis_n2(x))
diff --git a/week04_dynamic_programming/stairs.py b/week04_dynamic_programming/stairs.py
new file mode 100644
index 0000000..10d3c6f
--- /dev/null
+++ b/week04_dynamic_programming/stairs.py
@@ -0,0 +1,33 @@
+from time import time
+
+
+def stairs_dp(s):
+    N = len(s)
+    d = [None] * N
+    d[0] = s[0]
+    d[1] = s[1]
+    for i in range(2, N):
+        d[i] = min(d[i - 1], d[i - 2]) + s[i]
+    return d[N - 1]
+
+
+def stairs_rec(s):
+    if len(s) <= 2:
+        return s[-1]
+    d1 = stairs_rec(s[1:]) + s[0]
+    d2 = stairs_rec(s[2:]) + s[1]
+    return min(d1, d2)
+
+
+if __name__ == '__main__':
+    N = int(input())
+    s = list(map(int, input().split()))
+    t1 = time()
+    print(stairs_dp(s))
+    t2 = time()
+    print(stairs_rec(s))
+    t3 = time()
+    dp_time = t2 - t1
+    rec_time = t3 - t2
+    print(f'Naive: {rec_time:.8f} sec')
+    print(f'DP: {dp_time:.8f} sec')