Skip to main content

Welcome to a Grasp lesson

Create a free account to keep studying and create your own study path.

Lesson 28

Dynamic Programming Suitability

Recommended resources

Hello! Welcome to the first lesson of our module on Dynamic Programming Foundations.

In our last lesson, we saw how memoization dramatically speeds up recursive functions like the one for Fibonacci numbers. We called this a "top-down" approach. You learned that by caching the results of subproblems, we avoid redundant calculations.

Today, we'll formalize the theory behind why this works and learn how to spot problems where this powerful technique can be applied. We're officially diving into Dynamic Programming (DP), a cornerstone of algorithm design, especially in competitive programming.

Your learning outcome for this lesson is to identify problems with optimal substructure and overlapping subproblems suitable for DP. Mastering this skill is the crucial first step before writing any DP code.

The Two Hallmarks of Dynamic Programming

Dynamic Programming isn't just a specific algorithm; it's a method for solving a certain class of problems. For a problem to be solvable with DP, it must exhibit two specific properties:

  1. Optimal Substructure
  2. Overlapping Subproblems

Think of it like a Venn diagram. A problem is a candidate for Dynamic Programming only if it lies in the intersection of these two categories.

Venn Diagram of Dynamic Programming Problem Characteristics
A problem must have both properties to be efficiently solvable with Dynamic Programming.

To get a precise definition of these two concepts, let's start with a quick reading.

Dynamic Programming for Beginners: A Step-by-Step Journey to Mastery

The article 'Dynamic Programming for Beginners' from AlgoCademy provides a very clear and concise table defining these two key concepts. This will give us a solid foundation for the rest of the lesson.

In the article, find the section 'Key Concepts: Overlapping Subproblems and Optimal Substructure'. Please study the table that defines these two terms.

Now, let's explore each of these properties in more detail with concrete examples.


1. Overlapping Subproblems

This is the property you're already familiar with from our last lesson. A problem has overlapping subproblems if a recursive algorithm ends up solving the exact same subproblem multiple times.

Remember the recursion tree for calculating Fibonacci numbers?

Fibonacci Recursion Tree Illustrating Overlapping Subproblems
To calculate `Fib(4)`, the naive recursive approach calculates `Fib(2)` twice and `Fib(1)` three times. These are the "overlapping subproblems."

Memoization worked precisely because it stored the result of Fib(2) the first time it was computed, making subsequent calls for it instantaneous.

A Beginner's Guide to Dynamic Programming

To reinforce this idea, let's watch a short segment from 'A Beginner's Guide to Dynamic Programming' by Matt Guest, which revisits the Fibonacci example to explain this concept.

Watch the video from 02:41 to 03:58. The video clearly illustrates how repeated function calls in the Fibonacci recursion tree demonstrate overlapping subproblems.

If a problem can be broken down into subproblems, but the subproblems don't overlap (like in Merge Sort, where each half of the array is sorted independently), then DP is not necessary. The "Divide and Conquer" strategy is sufficient.


2. Optimal Substructure

This property is a bit more subtle but just as important. A problem has optimal substructure if the optimal solution to the overall problem can be constructed from the optimal solutions of its subproblems.

In simpler terms: if you want the best solution for the big problem, you need to find the best solutions for its smaller parts.

The classic example is finding the shortest path between two cities.

A Beginner's Guide to Dynamic Programming

The same 'Beginner's Guide' video provides a great, intuitive explanation of optimal substructure using a shortest path example.

Now, watch the earlier part of the video, from 01:39 to 02:41. Notice how the shortest path from San Francisco to San Diego is composed of the shortest path from SF to LA and the shortest path from LA to San Diego.

A Counterexample: When Optimal Substructure Fails

To truly understand a concept, it's helpful to see when it doesn't apply. Consider the Longest Path problem in a graph (without cycles). You might think it's similar to the Shortest Path problem, but it critically lacks optimal substructure. A subproblem's optimal solution (the longest path between two intermediate points) might not be part of the overall optimal solution.

Dynamic Programming | Set 2 (Optimal Substructure Property) | GeeksforGeeks

The GeeksforGeeks channel has an excellent video that first reinforces the shortest path example and then clearly demonstrates why the Longest Path problem does not have optimal substructure.

Watch the video from 00:39 to 02:12. Pay close attention to the counterexample starting at 01:13. It shows how combining the longest paths of subproblems can create a cycle or lead to a suboptimal overall path.

This distinction is crucial. The guarantee that optimal sub-solutions lead to a global optimum is what allows DP to build its way up to the correct final answer.

Test your understanding!

Consider the Coin Change problem: Find the minimum number of coins to make change for an amount A, using a given set of coin denominations.

For example, to make 7 cents with coins {1, 3, 4}, the optimal solution is 2 coins (3+4).

Which of the two DP properties does this statement illustrate?

  • "The minimum number of coins to make change for 7 cents is 1 + (the minimum coins needed for either 6, 4, or 3 cents)."
Show answer

This statement illustrates Optimal Substructure. It claims that the optimal solution for 7 cents can be constructed from the optimal solutions of its subproblems (making change for 6, 4, or 3 cents).

The Overlapping Subproblems property would be demonstrated by noticing that, for example, the solution for 4 cents is needed when calculating the solution for 7 cents (7-3) and also when calculating for 5 cents (5-1).


A Checklist for Identifying DP Problems

As a competitive programmer, your first task is to correctly classify a problem. Here’s a mental checklist to run through when you suspect a problem might be suitable for DP:

  1. Can you formulate a recursive solution? Try to define the solution for a state n in terms of solutions for smaller states (e.g., n-1, n-2, n/2). This is the first hint that a problem might have the right structure.

  2. Do you encounter Overlapping Subproblems? Trace a small example of your recursive solution. Do you see the same function call appearing in different branches of the recursion tree? If yes, this is a strong signal for DP.

  3. Does the problem have Optimal Substructure? Ask yourself: "Is the optimal solution to my problem guaranteed to be a combination of the optimal solutions to my subproblems?" If the answer is yes, DP is the way to go. If a locally "worse" choice could lead to a better overall outcome, DP might not work.

Let's apply this checklist to the Coin Change problem.

  • Recursive Solution? Yes. min_coins(A) = 1 + min(min_coins(A - c)) for every coin c in our set.
  • Overlapping Subproblems? Yes. To find min_coins(7) with {1, 3, 4}, we explore min_coins(6), min_coins(4), and min_coins(3). To find min_coins(6), we explore min_coins(5), min_coins(3), and min_coins(2). Notice min_coins(3) is needed in both paths.
  • Optimal Substructure? Yes. The principle of optimality holds. The best way to make change for amount A must involve a first coin c combined with the best way to make change for A - c.

Conclusion: Coin Change is a classic DP problem.


Common DP Problem Patterns

Over time, you'll develop an intuition for recognizing DP problems. Many of them fall into recognizable patterns.

A Beginner's Guide to Dynamic Programming

The 'Beginner's Guide' video concludes with a fantastic overview of five common patterns found in DP problems on platforms like LeetCode. Recognizing these can give you a huge head start.

Watch the final segment from 04:36 to 07:01. The video lists five indicators: sequential decision-making, greedy choice property, state transition, problems on paths/arrays, and counting/maximization/minimization tasks. Try to think about how these patterns relate to the two core properties we've discussed.

Keeping these patterns in mind will help you quickly categorize problems during a competition. If a problem asks you to find the "number of ways," the "minimum/maximum value," or the "longest/shortest sequence," your "DP senses" should start tingling.


Conclusion

In this lesson, we laid the theoretical groundwork for Dynamic Programming. You now have the essential knowledge to determine if a problem is a good candidate for a DP solution.

Key Takeaways:

  • A problem is suitable for Dynamic Programming if and only if it possesses both Optimal Substructure and Overlapping Subproblems.
  • Optimal Substructure means the global optimal solution can be built from the optimal solutions of its subproblems.
  • Overlapping Subproblems means a recursive approach would solve the same subproblems multiple times, creating an opportunity for optimization through memoization or tabulation.
  • Identifying these two properties is the most critical step in solving a DP problem.

Up Next:
Now that you can identify what problems to solve with DP, the next step is to learn how to set up the solution. In our next lesson, we will focus on formulating a DP recurrence relation, the mathematical formula that defines the solution for one state in terms of others. This is the heart of any DP algorithm.