Dynamic Programming
Dynamic Programming
1. Optimal Substructure:
The optimal solution to the larger problem depends on the optimal solutions to
smaller subproblems.
2. Overlapping Subproblems:
The large problem contains subproblems that are repeated many times. The results
of these subproblems can be stored and reused to avoid redundant calculations.
3. Memoization or Tabulation:
To optimize the performance of algorithms by reducing the time complexity of
problems involving repeated calculations:
o Memoization: Storing results during recursive calls (Top-Down approach).
o Tabulation: Building results from the smallest to the largest using a table
(Bottom-Up approach).
The goal of both: Avoid recalculating the same values.
4. Design an Appropriate Data Structure to Store Results:
For example, a one-dimensional or two-dimensional array, or a HashMap,
depending on the problem's nature.
5. Formulate the Recurrence Relation:
A mathematical relationship that connects the overall solution with solutions to
smaller subproblems.
6. Identify the Base Cases:
These are known solutions to smaller problems and are used as the starting point in
both memoization and tabulation.
❖ Fibonacci Numbers:
The Fibonacci sequence is a series of numbers where:
• Each number is the sum of the two preceding ones.
• It starts as:
o F(0) = 0
o F(1) = 1
o Then:
Dynamic Programming 2 Dr. Rafat alhanani
o F(2) = F(1) + F(0) = 1
o F(3) = F(2) + F(1) = 2
o F(4) = F(3) + F(2) = 3
o F(5) = F(4) + F(3) = 5
o And so on...
The sequence looks like this: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, ...
Applications of the Fibonacci Sequence:
1. In Engineering, Design, and Arts:
o The Golden Ratio extracted from the sequence is used in:
▪ Graphic design
▪ Architecture
▪ Logos (e.g., Twitter logo)
2. In Nature and the Environment:
o The Fibonacci sequence appears in:
▪ Leaf arrangements
▪ Petal count in flowers
▪ Growth patterns in shells and pineapples
▪ Seed distribution in sunflowers
Because the ratio between consecutive numbers approaches the "Golden Ratio" (≈ 1.618),
which frequently appears in nature.
Application: Drawing the "Fibonacci Spiral" :
Draw squares with side lengths from the Fibonacci sequence, then draw an arc inside
each square, creating a shape known as the Golden Spiral.
This shape appears in:
• Shells
• Galaxies
• Roses
• Even in professional logo designs!
❖ Staircase Problem:
A person stands at the bottom of a staircase with n steps. In each step, they can either
climb one step or two steps. How many different ways can they reach the top (step n)?
Example: If the number of steps n = 3, the possible ways are:
• 1→1→1
• 1→2
• 2→1
So, the result is 3 different ways.
Dynamic Programming Principles in This Example:
1. Optimal Substructure: To reach step n, we need the optimal solution for n-1 and
n-2. Hence, the larger problem depends on solutions to smaller problems.
2. Overlapping Subproblems: When using the recursive approach, we calculate
climbStairs(2) multiple times, and also climbStairs(1). These are repetitive
subproblems, and thus their results can be saved.
3. Memoization or Tabulation: In this case, we use Tabulation, where we build the
results from the smallest step (0) to n.
#include <stdio.h>
int climbStairs(int n) {
if (n <= 1) return 1;
int dp[n + 1]; // Array to store the number of ways for each step
dp[0] = 1; // Base case: 1 way to stay at the bottom (step 0)
dp[1] = 1; // Base case: 1 way to reach the first step (step 1)
for (int i = 2; i <= n; i++) {
dp[i] = dp[i - 1] + dp[i - 2]; // Sum of ways to reach the previous two steps
}
return dp[n]; // The final answer is stored at dp[n]
}
int main() {
int n = 5;
This approach reduces the time complexity from O(2^n) to O(n), making it more efficient.