Skip to content

Commit 20009b0

Browse files
Created Dynamic Programming
1 parent dbd9fd9 commit 20009b0

File tree

1 file changed

+132
-0
lines changed

1 file changed

+132
-0
lines changed
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
# Dynamic Programming
2+
3+
Dynamic programming is a method for solving complex problems by breaking them down into simpler subproblems and solving each subproblem only once. It stores the solutions to subproblems to avoid redundant computations, making it particularly useful for optimization problems where the solution can be obtained by combining solutions to smaller subproblems.
4+
5+
## Real-Life Examples of Dynamic Programming
6+
- **Fibonacci Sequence:** Computing the nth Fibonacci number efficiently.
7+
- **Shortest Path:** Finding the shortest path in a graph from a source to a destination.
8+
- **String Edit Distance:** Calculating the minimum number of operations required to transform one string into another.
9+
- **Knapsack Problem:** Maximizing the value of items in a knapsack without exceeding its weight capacity.
10+
11+
# Some Common Dynamic Programming Techniques
12+
13+
# 1. Fibonacci Sequence
14+
15+
The Fibonacci sequence is a classic example used to illustrate dynamic programming. It is a series of numbers where each number is the sum of the two preceding ones, usually starting with 0 and 1.
16+
17+
**Algorithm Overview:**
18+
- **Base Cases:** The first two numbers in the Fibonacci sequence are defined as 0 and 1.
19+
- **Memoization:** Store the results of previously computed Fibonacci numbers to avoid redundant computations.
20+
- **Recurrence Relation:** Compute each Fibonacci number by adding the two preceding numbers.
21+
22+
## Fibonacci Sequence Code in Python (Top-Down Approach with Memoization)
23+
24+
```python
25+
def fibonacci(n, memo={}):
26+
if n in memo:
27+
return memo[n]
28+
if n <= 1:
29+
return n
30+
memo[n] = fibonacci(n-1, memo) + fibonacci(n-2, memo)
31+
return memo[n]
32+
33+
n = 10
34+
print(f"The {n}th Fibonacci number is: {fibonacci(n)}.")
35+
```
36+
37+
## Fibonacci Sequence Code in Python (Bottom-Up Approach)
38+
39+
```python
40+
def fibonacci(n):
41+
fib = [0, 1]
42+
for i in range(2, n + 1):
43+
fib.append(fib[i - 1] + fib[i - 2])
44+
return fib[n]
45+
46+
n = 10
47+
print(f"The {n}th Fibonacci number is: {fibonacci(n)}.")
48+
```
49+
50+
## Complexity Analysis
51+
- **Time Complexity**: O(n) for both approaches
52+
- **Space Complexity**: O(n) for the top-down approach (due to memoization), O(1) for the bottom-up approach
53+
54+
</br>
55+
<hr>
56+
</br>
57+
58+
# 2. Longest Common Subsequence
59+
60+
The longest common subsequence (LCS) problem is to find the longest subsequence common to two sequences. A subsequence is a sequence that appears in the same relative order but not necessarily contiguous.
61+
62+
**Algorithm Overview:**
63+
- **Base Cases:** If one of the sequences is empty, the LCS is empty.
64+
- **Memoization:** Store the results of previously computed LCS lengths to avoid redundant computations.
65+
- **Recurrence Relation:** Compute the LCS length by comparing characters of the sequences and making decisions based on whether they match.
66+
67+
## Longest Common Subsequence Code in Python (Top-Down Approach with Memoization)
68+
69+
```python
70+
def longest_common_subsequence(X, Y, m, n, memo={}):
71+
if (m, n) in memo:
72+
return memo[(m, n)]
73+
if m == 0 or n == 0:
74+
return 0
75+
if X[m - 1] == Y[n - 1]:
76+
memo[(m, n)] = 1 + longest_common_subsequence(X, Y, m - 1, n - 1, memo)
77+
else:
78+
memo[(m, n)] = max(longest_common_subsequence(X, Y, m, n - 1, memo),
79+
longest_common_subsequence(X, Y, m - 1, n, memo))
80+
return memo[(m, n)]
81+
82+
X = "AGGTAB"
83+
Y = "GXTXAYB"
84+
print("Length of Longest Common Subsequence:", longest_common_subsequence(X, Y, len(X), len(Y)))
85+
```
86+
87+
## Complexity Analysis
88+
- **Time Complexity**: O(m * n) for the top-down approach, where m and n are the lengths of the input sequences
89+
- **Space Complexity**: O(m * n) for the memoization table
90+
91+
</br>
92+
<hr>
93+
</br>
94+
95+
# 3. 0-1 Knapsack Problem
96+
97+
The 0-1 knapsack problem is a classic optimization problem where the goal is to maximize the total value of items selected while keeping the total weight within a specified limit.
98+
99+
**Algorithm Overview:**
100+
- **Base Cases:** If the capacity of the knapsack is 0 or there are no items to select, the total value is 0.
101+
- **Memoization:** Store the results of previously computed subproblems to avoid redundant computations.
102+
- **Recurrence Relation:** Compute the maximum value by considering whether to include the current item or not.
103+
104+
## 0-1 Knapsack Problem Code in Python (Top-Down Approach with Memoization)
105+
106+
```python
107+
def knapsack(weights, values, capacity, n, memo={}):
108+
if (capacity, n) in memo:
109+
return memo[(capacity, n)]
110+
if n == 0 or capacity == 0:
111+
return 0
112+
if weights[n - 1] > capacity:
113+
memo[(capacity, n)] = knapsack(weights, values, capacity, n - 1, memo)
114+
else:
115+
memo[(capacity, n)] = max(values[n - 1] + knapsack(weights, values, capacity - weights[n - 1], n - 1, memo),
116+
knapsack(weights, values, capacity, n - 1, memo))
117+
return memo[(capacity, n)]
118+
119+
weights = [10, 20, 30]
120+
values = [60, 100, 120]
121+
capacity = 50
122+
n = len(weights)
123+
print("Maximum value that can be obtained:", knapsack(weights, values, capacity, n))
124+
```
125+
126+
## Complexity Analysis
127+
- **Time Complexity**: O(n * W) for the top-down approach, where n is the number of items and W is the capacity of the knapsack
128+
- **Space Complexity**: O(n * W) for the memoization table
129+
130+
</br>
131+
<hr>
132+
</br>

0 commit comments

Comments
 (0)