Unit 5: Dynamic Programming (8 HRS) : Pyqs
Unit 5: Dynamic Programming (8 HRS) : Pyqs
Working Method
• Greedy:
○ Pick the best immediate option (locally best), hoping it leads to global best.
○ No backtracking.
• Dynamic Programming:
○ Solve and remember results of smaller subproblems.
○ Combine subproblem solutions to get overall solution.
○ May explore multiple choices before finalizing.
Conditions to Use
Condition Greedy Dynamic Programming
Greedy choice property required? Yes No
Overlapping subproblems needed? No Yes
Optimal substructure required? Yes Yes
1. Optimal Substructure
• Definition: A problem exhibits optimal substructure if the solution to the problem can be constructed
efficiently from the solutions to its subproblems.
• Example: In the Matrix Chain Multiplication problem, the optimal way to multiply matrices is
determined by the optimal ways to multiply smaller subsequences of matrices.
2. Table Structure
• Definition: A table (usually a 2D array) is used to store the solutions to subproblems in Dynamic
Programming. This is where the results of smaller subproblems are stored to avoid redundant
computations.
• Structure: The table is typically filled iteratively, and each entry in the table corresponds to a
subproblem's solution.
• Example: In the 0/1 Knapsack Problem, we use a table where dp[i][w] stores the maximum value that
can be achieved with the first i items and capacity w.
3. Bottom-Up Approach
• Definition: In the Bottom-Up approach, the problem is solved by first solving the smallest subproblems
and then using those solutions to build up to the solution for the larger problem.
• Process: You fill the DP table from the smallest subproblems (base cases) and iteratively compute the
larger problems until you reach the desired result.
• Example: In the Fibonacci Sequence, we compute the Fibonacci numbers starting from the base cases
(F(0) and F(1)) and then build up the results until we reach the desired Fibonacci number.
daa 5
Memoization (Concept)
• Memoization = Remembering solutions of subproblems.
• Solve the problem top-down (start from the big problem and recursively solve subproblems).
• Whenever you solve a subproblem, store its result (in a table or dictionary).
• If you need the same subproblem again, reuse the stored result — don't recompute.
• Speeds up recursion by avoiding repeated calculations.