Skip to content

Commit 5f3fa64

Browse files
committed
Three-Hundred-Seventeen Commit: Amend Dynamic_Programming_Tutorial.txt in Dynamic Programming section
1 parent 70f695a commit 5f3fa64

File tree

5 files changed

+621
-551
lines changed

5 files changed

+621
-551
lines changed

src/Dynamic_Programming/Dynamic_Programming_Tutorial.txt

Lines changed: 101 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ Dynamic Programming
1111
The main idea behind dynamic programming is to store the results of subproblems to avoid redundant computations.
1212
This technique is known as "memoization" when done top-down (recursively) and "tabulation" when done bottom-up (iteratively).
1313

14-
1. Key Concepts in Dynamic Programming
14+
1. Key Concepts in Dynamic Programming:
15+
---------------------------------------
1516

1617
1. Optimal Substructure:
1718
- A problem exhibits optimal substructure if an optimal solution to the problem can be constructed from optimal solutions
@@ -21,7 +22,8 @@ Dynamic Programming
2122
- A problem has overlapping subproblems if the same subproblems are solved multiple times during the computation of the
2223
overall problem.
2324

24-
2. Steps to Apply Dynamic Programming
25+
2. Steps to Apply Dynamic Programming:
26+
--------------------------------------
2527

2628
1. Characterize the Structure of an Optimal Solution:
2729
- Understand how to construct the optimal solution using solutions to subproblems.
@@ -36,7 +38,8 @@ Dynamic Programming
3638
4. Construct the Optimal Solution (if needed):
3739
- Trace back the stored results to construct the actual solution.
3840

39-
3. Examples of Dynamic Programming
41+
3. Examples of Dynamic Programming:
42+
-----------------------------------
4043

4144
1. Fibonacci Sequence:
4245
- The Fibonacci sequence can be defined as F(n) = F(n-1) + F(n-2) with base cases F(0) = 0 and F(1) = 1.
@@ -53,15 +56,17 @@ Dynamic Programming
5356
- Dynamic programming can be used to fill a table where each entry L[i][j] represents the length of the LCS of the
5457
first i elements of one sequence and the first j elements of the other.
5558

56-
4. Advantages of Dynamic Programming
59+
4. Advantages of Dynamic Programming:
60+
-------------------------------------
5761

5862
- Efficiency: By storing the results of subproblems, dynamic programming reduces the time complexity of solving complex problems.
5963
- Optimization: It guarantees finding the optimal solution if the problem has optimal substructure and overlapping subproblems.
6064

61-
5. Disadvantages of Dynamic Programming
65+
5. Disadvantages of Dynamic Programming:
66+
----------------------------------------
6267

63-
- Space Complexity: Storing all subproblem results can require significant memory.
64-
- Complexity in Implementation: Understanding and correctly applying dynamic programming can be challenging.
68+
- Space Complexity: Storing all subproblem results can require significant memory.
69+
- Complexity in Implementation: Understanding and correctly applying dynamic programming can be challenging.
6570

6671
Dynamic programming is a powerful tool for solving a wide range of problems, particularly those involving optimization and
6772
recursive substructure.
@@ -73,114 +78,118 @@ Dynamic Programming
7378
Both approaches aim to solve complex problems by breaking them down into simpler subproblems, but they differ in how they handle
7479
the subproblems and store intermediate results.
7580

76-
1. Top-Down Approach (Memoization)
81+
1. Top-Down Approach (Memoization):
82+
-----------------------------------
7783

7884
The top-down approach involves solving the problem recursively and storing the results of subproblems to avoid redundant computations.
7985
This is known as memoization.
8086

81-
* Steps in Top-Down Approach:
87+
* Steps in Top-Down Approach:
88+
-----------------------------
8289

83-
1. Recursive Formulation:
84-
- Define the problem recursively in terms of smaller subproblems.
90+
1. Recursive Formulation:
91+
- Define the problem recursively in terms of smaller subproblems.
8592

86-
2. Memoization:
87-
- Use a data structure (usually a dictionary or an array) to store the results of subproblems.
93+
2. Memoization:
94+
- Use a data structure (usually a dictionary or an array) to store the results of subproblems.
8895

89-
3. Check and Reuse:
90-
- Before solving a subproblem, check if its result is already computed and stored. If so, reuse the stored result.
96+
3. Check and Reuse:
97+
- Before solving a subproblem, check if its result is already computed and stored. If so, reuse the stored result.
9198

92-
4. Base Cases:
93-
- Define the base cases to stop the recursion.
99+
4. Base Cases:
100+
- Define the base cases to stop the recursion.
94101

95-
* Example (Fibonacci Sequence):
102+
* Example (Fibonacci Sequence):
103+
-------------------------------
96104

97-
In the top-down approach, we use recursion and store the results of subproblems to avoid redundant computations.
98-
This involves using a data structure like an array or a HashMap to store intermediate results.
105+
In the top-down approach, we use recursion and store the results of subproblems to avoid redundant computations.
106+
This involves using a data structure like an array or a HashMap to store intermediate results.
99107

100-
import java.util.HashMap;
101-
import java.util.Map;
108+
import java.util.HashMap;
109+
import java.util.Map;
102110

103-
public class FibonacciTopDown {
104-
private Map<Integer, Integer> memo = new HashMap<>();
111+
public class FibonacciTopDown {
112+
private Map<Integer, Integer> memo = new HashMap<>();
105113

106-
public int fib(int n) {
107-
if (memo.containsKey(n)) {
108-
return memo.get(n);
109-
}
110-
if (n <= 1) {
111-
return n;
112-
}
113-
int result = fib(n - 1) + fib(n - 2);
114-
memo.put(n, result);
115-
return result;
116-
}
117-
118-
public static void main(String[] args) {
119-
FibonacciTopDown fibonacci = new FibonacciTopDown();
120-
System.out.println(fibonacci.fib(10)); // Output: 55
121-
}
122-
}
114+
public int fib(int n) {
115+
if (memo.containsKey(n)) {
116+
return memo.get(n);
117+
}
118+
if (n <= 1) {
119+
return n;
120+
}
121+
int result = fib(n - 1) + fib(n - 2);
122+
memo.put(n, result);
123+
return result;
124+
}
123125

126+
public static void main(String[] args) {
127+
FibonacciTopDown fibonacci = new FibonacciTopDown();
128+
System.out.println(fibonacci.fib(10)); // Output: 55
129+
}
130+
}
124131

125-
2. Bottom-Up Approach (Tabulation)
132+
2. Bottom-Up Approach (Tabulation):
133+
-----------------------------------
126134

127135
The bottom-up approach involves solving the problem iteratively, starting from the smallest subproblems and building
128136
up to the solution of the original problem. This is known as tabulation.
129137

130-
* Steps in Bottom-Up Approach:
131-
132-
1. Iterative Formulation:
133-
- Define the problem iteratively, starting from the smallest subproblems.
134-
135-
2. Table Initialization:
136-
- Use a data structure (usually an array) to store the results of subproblems.
137-
138-
3. Iterative Computation:
139-
- Compute the results of subproblems in a specific order, usually from the smallest to the largest.
140-
141-
4. Final Solution:
142-
- The final solution to the original problem is obtained from the last computed value in the table.
143-
144-
* Example (Fibonacci Sequence):
145-
146-
In the bottom-up approach, we iteratively solve the problem from the smallest subproblems up to the original problem,
147-
storing intermediate results in a data structure like an array.
148-
149-
public class FibonacciBottomUp {
150-
public int fib(int n) {
151-
if (n <= 1) {
152-
return n;
138+
* Steps in Bottom-Up Approach:
139+
------------------------------
140+
141+
1. Iterative Formulation:
142+
- Define the problem iteratively, starting from the smallest subproblems.
143+
144+
2. Table Initialization:
145+
- Use a data structure (usually an array) to store the results of subproblems.
146+
147+
3. Iterative Computation:
148+
- Compute the results of subproblems in a specific order, usually from the smallest to the largest.
149+
150+
4. Final Solution:
151+
- The final solution to the original problem is obtained from the last computed value in the table.
152+
153+
* Example (Fibonacci Sequence):
154+
-------------------------------
155+
156+
In the bottom-up approach, we iteratively solve the problem from the smallest subproblems up to the original problem,
157+
storing intermediate results in a data structure like an array.
158+
159+
public class FibonacciBottomUp {
160+
public int fib(int n) {
161+
if (n <= 1) {
162+
return n;
163+
}
164+
int[] dp = new int[n + 1];
165+
dp[0] = 0;
166+
dp[1] = 1;
167+
for (int i = 2; i <= n; i++) {
168+
dp[i] = dp[i - 1] + dp[i - 2];
169+
}
170+
return dp[n];
171+
}
172+
173+
public static void main(String[] args) {
174+
FibonacciBottomUp fibonacci = new FibonacciBottomUp();
175+
System.out.println(fibonacci.fib(10)); // Output: 55
176+
}
153177
}
154-
int[] dp = new int[n + 1];
155-
dp[0] = 0;
156-
dp[1] = 1;
157-
for (int i = 2; i <= n; i++) {
158-
dp[i] = dp[i - 1] + dp[i - 2];
159-
}
160-
return dp[n];
161-
}
162-
163-
public static void main(String[] args) {
164-
FibonacciBottomUp fibonacci = new FibonacciBottomUp();
165-
System.out.println(fibonacci.fib(10)); // Output: 55
166-
}
167-
}
168-
169178

170179
* Comparison of Top-Down and Bottom-Up Approaches
171180

172-
- Top-Down (Memoization):
173-
- Uses recursion and stores intermediate results.
174-
- More intuitive for problems naturally expressed in recursive form.
175-
- May lead to high recursion depth and potential stack overflow for very large problems.
176-
- Can be easier to implement if the recursive solution is straightforward.
177-
178-
- Bottom-Up (Tabulation):
179-
- Uses iteration and builds up solutions from smaller subproblems.
180-
- Typically more space-efficient because it can often be optimized to use a fixed amount of space (e.g., only
181-
storing the last two values for Fibonacci).
182-
- Avoids recursion depth issues.
183-
- Can be more complex to implement if the iterative solution is not obvious.
181+
- Top-Down (Memoization):
182+
- Uses recursion and stores intermediate results.
183+
- More intuitive for problems naturally expressed in recursive form.
184+
- May lead to high recursion depth and potential stack overflow for very large problems.
185+
- Can be easier to implement if the recursive solution is straightforward.
186+
187+
- Bottom-Up (Tabulation):
188+
- Uses iteration and builds up solutions from smaller subproblems.
189+
- Typically more space-efficient because it can often be optimized to use a fixed amount of space (e.g., only
190+
storing the last two values for Fibonacci).
191+
- Avoids recursion depth issues.
192+
- Can be more complex to implement if the iterative solution is not obvious.
184193

185194
Both approaches ultimately achieve the same goal: solving the problem efficiently by leveraging the solutions to subproblems.
186195
The choice between top-down and bottom-up depends on the specific problem and the programmer's preference or constraints.

0 commit comments

Comments
 (0)