Template For Dynamic programming
20173

Dynmaic Programming For Practice

Sharing some topic wise good Dynamic Programming problems and sample solutions to observe on how to approach.

1.Unbounded Knapsack or Target sum
Identify if problems talks about finding groups or subset which is equal to given target.

https://leetcode.com/problems/target-sum/
https://leetcode.com/problems/partition-equal-subset-sum/
https://leetcode.com/problems/last-stone-weight-ii/
https://leetcode.com/problems/shortest-subarray-with-sum-at-least-k/

All the above problems can be solved by 01 Knapsack or Target sum algo with minor tweaks.
Below is a standard code for 01 knapsack or target sum problems.


int 01 knacsack(vector<int>& nums,vector<int>& v, int w)  // nums array , w total amount that have to collect 
    {                                                     // v value array
        int n=nums.size();
		
        vector<vector<bool>> d(n+1,vector<bool>(w+1,0));  
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=w;j++)
            {
                if(j<nums[i-1])  
                {
                    d[i][j]=d[i-1][j];
                }
                else if(nums[i-1]<=j)
                {
                    d[i][j]=max(v[i-1]+d[i-1][j-nums[i-1]],d[i-1][j]);
                }
            }
        }
        
        return d[n][w];
        
    }

Funtion for Target sum

int countsubset(vector<int>& nums, int w) 
    {
	    int n=nums.size();
		
        vector<vector<bool>> d(n+1,vector<bool>(w+1));
        for(int i=0;i<=n;i++)
        {
                d[i][0]=1;
        }
        for(int i=1;i<=w;i++)
        {
                d[0][i]=0;
        }
        
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=w;j++)
            {
                if(j<nums[i-1])
                {
                    d[i][j]=d[i-1][j];
                }
                else if(nums[i-1]<=j)
                {
                    d[i][j]=d[i-1][j-nums[i-1]] + d[i-1][j];
                }
            }
        }
        
        return d[n][w];
    }

2.Unbounded Knapsack
Identify if problems talks about finding groups or subset which is equal to given target and repetition is allowed.

https://leetcode.com/problems/coin-change-2/
https://leetcode.com/problems/coin-change/

All the above problems can be solved by unbounded Knapsack algo with minor tweaks.
Below is a standard code for 01 knapsack or target sum problems.

int unboundedknacsack(vector<int>& nums,vector<int>& v, int w) 
    {
        int n=nums.size();
		
        vector<vector<bool>> d(n+1,vector<bool>(w+1,0));
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=w;j++)
            {
                if(j<nums[i-1])
                {
                    d[i][j]=d[i-1][j];
                }
                else if(nums[i-1]<=j)
                {
                    d[i][j]=max(v[i-1]+d[i][j-v[i-1]],d[i-1][j]);
                }
            }
        }
        
        return d[n][w];
    }

or

       int change(int amount, vector<int>& coins) 
    {
       vector<vector<int>> d(coins.size()+1,vector<int>(amount+1));
        
       for(int i=0;i<=coins.size();i++)
       {
           d[i][0]=1;
       }
        for(int i=1;i<=amount;i++)
       {
           d[0][i]=0;
       }
        
        for(int i=1;i<=coins.size();i++)
       {
           for(int j=1;j<=amount;j++)
           {
               if(j<coins[i-1])
               {
                   d[i][j]=d[i-1][j];
               }
               
               else if(j>=coins[i-1])
               {
                   d[i][j]=(d[i][j-coins[i-1]]+d[i-1][j]);
               }
           }
       }
        
        return d[coins.size()][amount]; 
    }

3.Longest Increasing Subsequence (LIS)

Identify if problems talks about finding longest increasing subset.

https://leetcode.com/problems/minimum-cost-to-cut-a-stick/
https://leetcode.com/problems/longest-increasing-subsequence/
https://leetcode.com/problems/largest-divisible-subset/
https://leetcode.com/problems/perfect-squares/
https://leetcode.com/problems/super-ugly-number/

https://leetcode.com/problems/russian-doll-envelopes/
https://leetcode.com/problems/maximum-height-by-stacking-cuboids/description/

@Nam_22 mentioning above two question .

All the above problems can be solved by longest Increasing subsequence algo with minor tweaks.
Below is a standard code for LIS problems.




    int lengthOfLIS(vector<int>& nums) 
    {
        vector<int> d(nums.size(),1);
        
        int m=0;
        for(int i=0;i<nums.size();i++)
        {
            for(int j=0;j<i;j++)
            {
                if(nums[j]<nums[i] && d[i]<d[j]+1)
                {
                    d[i]=d[j]+1;
                }
            }
            m=max(d[i],m);
        }
    
        return m;
    }

longest bitonic subsequence

int lbs(vector<int> v)
{
    vector<int> lis(v.size(),1);
    vector<int> lds(v.size(),1);
    
   for(int i=0;i<v.size();i++)
    {
        
        for(int j=0;j<i;j++)
        {
            if(v[j]<v[i] && lis[i]<lis[j]+1)
            {
             lis[i]=lis[j]+1;
            }
        }

    }
    
   for(int i=v.size()-2;i>0;i--)
    {
       
       for(int j=v.size()-1;j>i;j--)
       {
           if(v[j]<v[i] && lds[i]<lds[j]+1)
          { 
             lds[i]=lds[j]+1;
          }
       }
       
    }
    
    int m=0;
    for(int i=0;i<v.size();i++)
    { 
        m=max(m,lis[i]+lds[i]-1);
    }
    
    return m;
}

4.Longest Common Subsequence

Identify if problems talks about finding longest common subset.

1.subsequence
https://leetcode.com/problems/longest-common-subsequence/
https://leetcode.com/problems/distinct-subsequences/
https://leetcode.com/problems/shortest-common-supersequence/
https://leetcode.com/problems/distinct-subsequences/
https://leetcode.com/problems/interleaving-string/

 int longestCommonSubsequence(string text1, string text2) 
    {
        int n1 = text1.size();
        int n2 = text2.size();
        vector<vector<int>> dp(n1+1,vector<int>(n2+1,0));
        

        for(int i=1;i<=n1;i++)
        {
            for(int j=1;j<=n2;j++)
            {
                if(text1[i-1] == text2[j-1])
                    dp[i][j] = 1+dp[i-1][j-1];
                else
                    dp[i][j] = max(dp[i-1][j], dp[i][j-1]);

            }
        }
        return dp[n1][n2];

    }

2.substring

https://leetcode.com/problems/maximum-length-of-repeated-subarray/

 int longestCommonSubstring(string text1, string text2) 
    {
        int n1 = text1.size();
        int n2 = text2.size();
        vector<vector<int>> dp(n1+1,vector<int>(n2+1,0));
        
        int r=0;
        for(int i=1;i<=n1;i++)
        {
            for(int j=1;j<=n2;j++)
            {
                if(text1[i-1] == text2[j-1])
                   { 
                     dp[i][j] = 1+dp[i-1][j-1];
                     r=max(dp[i][j],r);
                   }
                else
                    dp[i][j] = 0;

            }
        }
        return dp[n1][n2];

    }

3.palindrome

https://leetcode.com/problems/longest-palindromic-substring/
https://leetcode.com/problems/longest-palindromic-subsequence/
https://leetcode.com/problems/minimum-insertion-steps-to-make-a-string-palindrome/
https://leetcode.com/problems/delete-operation-for-two-strings/

int lps(string s1)
{
    int n1=s1.length();
    string s2=s1;
    reverse(s2.begin(),s2.end());
    int n2=s2.length();
    
    vector<vector<int>> dp(n1+1,vector<int>(n2+1,0));
    
    for(int i=1;i<=n1;i++)
    {
        for(int j=1;j<=n2;j++)
        {
            if(s1[i-1]==s2[j-1])
            dp[i][j]=1+dp[i-1][j-1];
            
            else
            dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
        }
    }
    
    return dp[n1][n2];
}

4.Print

string longestCommonSubsequence(string a) 
{
   string b=a;
   reverse(b.begin(),b.end());
   
   int n1=a.size();
   int n2=b.size();
   vector<vector<int>> d(n1+1,vector<int>(n2+1,0));
   
   for(int i=1;i<=n1;i++)
   {
       for(int j=1;j<=n2;j++)
       {
           if(a[i-1]==b[j-1])
           {
               d[i][j]=1+d[i-1][j-1];
           }
           else
           {
               d[i][j]=max(d[i-1][j],d[i][j-1]);
           }
       }
   }
   
   string v;
   int i=n1,j=n2;
   while(i>0 && j>0)
   {
       if(a[i-1]==b[j-1])
       {
           v.push_back(a[i-1]);
           i--;
           j--;
       }
       
       else
       {
           if(d[i-1][j]>d[i][j-1])
           {
               i--;
           }
           else
           {
               j--;
           }
       }
   }
   reverse(v.begin(),v.end());
   return v;
}

5.Gap Method Problems

General Dp problem which is solved by Gap method

https://leetcode.com/problems/count-different-palindromic-subsequences/
https://leetcode.com/problems/palindrome-partitioning-ii/
https://leetcode.com/problems/minimum-score-triangulation-of-polygon/

And Leetcode stones problem set are also included.

All the above problems can be solved by gap methodwith minor tweaks.
Below is a standard code for gap method code.

count palindromic subsequence

   int countPalindromicSubsequences(string s) 
    {
      int d[s.length()][s.length()];  
    
      for(int g=0;g<s.length();g++)
      {
          for(int i=0,j=g;j<s.length();i++,j++)
          {
              if(g==0)
              {
                  d[i][j]=1;
              }
              else if(g==1)
              {
                  if(s[i]==s[j])
                  {
                      d[i][j]=3;
                  }
                  else
                  {
                      d[i][j]=2;
                  }
              }
              
              else
              {
                  if(s[i]==s[j])
                  {
                      d[i][j]=d[i][j-1]+d[i+1][j]+1;
                  }
                  else
                  {
                      d[i][j]=d[i][j-1]+d[i+1][j]-d[i+1][j-1];
                  }
              }
          }
      }
        
        return d[0][s.length()-1];
    }

6.Kadans algo

Identify if problems talks about finding the maximum subarray sum.

https://leetcode.com/problems/best-time-to-buy-and-sell-stock/
https://leetcode.com/problems/best-time-to-buy-and-sell-stock-ii/
https://leetcode.com/problems/maximum-absolute-sum-of-any-subarray/
https://leetcode.com/problems/arithmetic-slices/
https://leetcode.com/problems/arithmetic-slices-ii-subsequence/
https://leetcode.com/problems/longest-turbulent-subarray/
https://leetcode.com/problems/k-concatenation-maximum-sum/
https://leetcode.com/problems/k-concatenation-maximum-sum/
https://leetcode.com/problems/length-of-longest-fibonacci-subsequence/
https://leetcode.com/problems/ones-and-zeroes/
https://leetcode.com/problems/maximum-sum-circular-subarray/

All the above problems can be solved by gap method with minor tweaks.
Below is a standard code for gap method code.

int kad(vector<int> v)
{
    int c=v[0],o=v[0];
    
    for(int i=1;i<n;i++)
    {
        if(c >= 0)
        {
            c=c+v[i];
        }
        else
        {
            c=v[i];
        }
        
         if(o<c)
        {
             o=c;
        }
        
    }
    
    return o;
}

7.Catalan

Identify if problems talks about counting the number of something.
eg node,bracket etc.

https://leetcode.com/problems/unique-binary-search-trees/

All the above problems can be solved by catalan with minor tweaks.
Below is a standard code for catalan code.

int cat(int n)
{
    int dp[n+1];
    dp[0]=1;
    dp[1]=1;
    for(int i = 2; i < n+1; i++)
    {
        dp[i]=0;
         for(int j = 0; j < i; j++)
         {
            dp[i] += dp[j] * dp[i - 1 - j];
         }
      }
    
    return dp[n];
}

Please correct the approach/solution if you find anything wrong.
And if you like my post then give a thumbs up : ) happy coding

Comments (26)