Dynamic Programming
Dynamic Programming
PREREQUISITES:
1) Recursion
2) Complexity
“Those who cannot remember the past are condemned to repeat it”
- Dynamic Programming
INTUITION:
Quoting directly from Jonathan Paulson’s answer(who is a Software Engineer at Google) to “How
should I explain dynamic programming to a 4-year-old?” on Quora:
OVERLAPPING SUBPROBLEMS:
Let us consider another problem.
Suppose I ask you to find the Nth fibonacci number recursively.
What is the base case? It is the case for which I already know the answer:
fib(1) = 1
fib(2) = 1
fib(5)
/ \
fib(4) fib(3)
/ \ / \
fib(3) fib(2) fib(2) fib(1)
/ \ / \ / \
fib(2) fib(1) fib(1) fib(0) fib(1) fib(0)
/ \
fib(1) fib(0)
If you observe the recursion tree carefully, you will see that we are calculating the sub problems:
fib(3) twice, fib(2) thrice, fib(1) 4 times etc.
The core idea of Dynamic Programming is to avoid repeated work by remembering partial results!
A PROBLEM:
Consider the following problem:
Given a list of N coins, their values (V1,V2,, … , VN), and the total sum S. Find the
minimum number of coins the sum of which is S (we can use as many coins of one type as
we want), or report that it’s not possible to select coins in such a way that they sum up to S.
We will write a dynamic programming solution (recursion with memoization) for the following
problem.
Let the state of our dp be dp[i]=minimum number of coins required to represent sum i.
Base Case:
What is the base case? How do we decide it?
For what value(s) of S do we already know the answer(i.e the minimum number of coins the
sum of which is S).
So our base case is if S is one of the values of the N coins, then we can represent that amount
using the coin of that value i.e
dp[V1] = 1
dp[V2] = 1
dp[V3] = 1
.
.
.
.
dp[VN] = 1
We definitely cannot do better than 1 coin!
Recursive Case:
Let us move on to the recursive case.
What is the minimum number of coins required to represent S?
Let us use a coin with value V1. In that case, what is the minimum number of coins required to
represent S? 1+minimum number of coins required to represent (S-V1). And we recursively
compute this i.e minimum number of coins required to represent (S-V1).
Let us use a coin with value V2. In that case, what is the minimum number of coins required to
represent S? 1+minimum number of coins required to represent (S-V2).
Let us use 1 coin with value V3. In that case what is the minimum number of coins required to
represent S? 1+minimum number of coins required to represent (S-V3).
.
.
.
Let us use 1 coin with value VN. In that case what is the minimum number of coins required to
represent S? 1+minimum number of coins required to represent (S-VN).
Let us look at how to convert all our ideas into code once we know the state of the dp, recursive
and base cases.
Link: https://ideone.com/xyApFf
Reference:
You may refer to this link Introduction(Beginner):
https://www.topcoder.com/community/data-science/data-science-tutorials/dynamic-programming
-from-novice-to-advanced/ for a more detailed analysis of the same problem.
Visualisation:
Have a look at this excellent visualization here:
https://www.cs.usfca.edu/~galles/visualization/DPChange.html
Instructions:
1. Enter a value of S in the text field on the top left corner of screen.
2. Click Change memoized.
3. Then enter the same value of S in the text field on the top left corner of screen.
4. Click Change recursive
5. Which one is faster!? ;)
ANOTHER PROBLEM:
You still haven’t got the flavour of what amazing tasks can be solved efficiently using dynamic
programming. Let us look at a more interesting problem.
Have a look at the first answer starting from subhead “Motivation Problem”, here:
https://www.quora.com/Are-there-any-good-resources-or-tutorials-for-dynamic-programming-be
sides-the-TopCoder-tutorial
This will give you an good idea as to what kind of problems can be solved using dynamic
programming!
CLASSIC DP PROBLEM #1:
Given a sequence of N numbers – A[0] , A[1] , …, A[N-1] . Find the length of the longest
non-decreasing sequence.
Let us first decide the state of the dp i.e what parameters we need, to describe the situation of
our problem.
State:
Let’s the state be dp[i] = the longest non-decreasing sequence ending with number A[i] .
Base Case:
What is our base case? What is the answer that we already know?
Don’t we know dp[0]?
What is dp[0]?
dp[0] is the longest non decreasing sequence ending at the 0th index. It is always 1!
Recursive Case:
Let us move onto the recursive case.
Let us consider an element say A[3].
Now we need to compute the longest non decreasing sequence ending at index 3.
How do we do it?
It is the maximum of the following cases:
1+dp[0], iff A[0]<=A[3]
1+dp[1], iff A[1]<=A[3]
1+dp[2], iff A[2]<=A[3]
^------>These conditions must be satisfied to get a nondecreasing sequence.
What we basically do is we consider all the elements before A[3] which is less than equal to A[3]
and see the longest non decreasing sequence ending at that element. Then we add 1 to that
answer to include A[3] in the sequence as well.
Final Answer:
Our longest non decreasing sequence of the given array will have it’s ending point at one of the
indices from 0 to N-1.
Therefore, the answer will be,
max(dp[0], dp[1], …...dp[N-1])
Reference:
Have a look at this tutorial elementary section for a more detailed solution:
https://www.topcoder.com/community/data-science/data-science-tutorials/dynamic-programming
-from-novice-to-advanced/
Conclusion:
Remember one thing dynamic programming is a topic that requires immense practice. Solve as
many problems as possible. Here we discussed only a few of the many variations possible.
Whenever you are solving a dynamic programming problem try to come up with the dp state to
describe the situation of the problem. Then figure out the base case, then the recursive case.
Memoize and done!
Make sure to try hard! If you are still unable to solve these, do give the editorials a read.
Further Reading:
http://www.iarcs.org.in/inoi/online-study-material/topics/dp.php
https://www.hackerearth.com/practice/notes/dynamic-programming-problems-involving-grids/
More resources:
https://www.commonlounge.com/discussion/52ae98d1a9e447f9a33968985e036a2a/main
https://www.commonlounge.com/discussion/3e462ec698ab4aaeb72af15bc8acb50f/main