DP Demystified | How to approach a dp problem| Simple 5min read

So After Solving DP Question for Quite a few days, I came up with some Summary that will help you through your DP Journey.
Here is my practical guide to solving DP problems.

  1. Think of the Recursion state: Define your dp[..][..]meaning e.g. for https://leetcode.com/problems/longest-increasing-subsequence/, dp[i] = the length of the longest increasing subsequence that ENDS on element i.

For Medium-Level there are 5Types of Forms Available:

    1. Knapsack type? {take it or not take it} -> example[Target sum, house robber 2]
    1. Ending With DP type? {best ending at this level}
    1. L-R DP type?
    1. GAME DP?
    1. Subsequence DP? [LCS, LIS, LPS]
  1. Think of Recursion Transitions

  2. When coming up with a recurrence relation, separately come up with a general case and base cases.

  3. People usually prefer either the top-down or the bottom-up style.

  4. At its core, DP problems are really graph problems. Here each dp[...][...][...] terms are nodes and edges are drawn based on recurrence relations. For your problem to have a DP solution, this graph MUST BE a DAG. This is usually what textbooks mean "optimal substructure". For me, this connection of DP to its graph representation greatly helped.

  5. Once you "get" the solid understanding, then solve problems to find and internalize common patterns.

**Example For Question: ** https://leetcode.com/problems/climbing-stairs/
Problem list : List 1
Problem list : List 2

Steps to think of any DP solution

  1. Form states and state meaning: int rec(level)-> returns the number of ways you can reach level to n by +1 and +2 steps
  2. Transitions rec(level) -> rec(level+1)
    -> rec(level +2)
  • Base Case
  • Pruning
  • Dp check
  • Computation
  • save and return

class Solution
{
    int dp[50]; // cache/dp array
    int n; // the level you want to reach
    int rec(
        int level) // rec(level)-> returns the possible ways you can reach n with +1 and +2 steps
    {
        // base case
        if (level == n)
            return 1;

        // cache check
        if (dp[level] != -1)
            return dp[level];
			
        // computation
        int ans = 0;
        if (level + 1 <= n)
        {
            ans += rec(level + 1);
        }
        if (level + 2 <= n)
        {
            ans += rec(level + 2);
        }
		
        // cache and return
        return dp[level] = ans;
    }

public:
    int climbStairs(int na)
    {
        n = na;
        memset(dp, -1, sizeof(dp)); // resetting dp array to -1
        return rec(0); // returning the value from level =0 to n with +1 and +2 steps
    }
};

One should have a mind make up of Recursion like this

image

DO GIVE STARS ⭐ ⭐ ⭐ ⭐ ⭐ ⭐ ⭐ ⭐ ⭐ ⭐ ⭐ ⭐ ⭐ ⭐ ⭐ ⭐ ⭐ ⭐ ⭐ ⭐ ⭐

Comments (1)