You are on page 1of 19

Dynamic Programming  

 
Introduction  
 
Dynamic Programing is all about remembering answers to the sub-problems you’ve already 
solved and not solving it again.  
 
Q. Where do we need Dynamic Programming?   
If you are given a problem, which can be broken down into smaller sub-problems. These smaller 
sub-problems can still be broken into smaller ones - and if you manage to find out that there are 
some over- lappping sub-problems. 
Then you’ve encountered a DP problem. 

  
 
Dynamic Programming is just a fancy way to say remembering stuff to save time later!”  
Dynamic Programming and Recursion: 
● Dynamic programming is basically, recursion plus memoization. 
● Recursion allows you to express the value of a function in terms of other values of that 
function.  
● if you implement your function in a way that the recursive calls are done in advance, and 
stored for easy access, it will make your program faster.   
This is what we call Memoization - it is memorizing the results of some specific states, which 
can then be later accessed to solve other sub-problems. 
 
 
 
 
 
MINIMUM STEPS TO ONE
http://www.spoj.com/problems/MST1/ 
On a positive integer, you can perform any one of the following 3 steps. 
1. Subtract 1 from it. 
2. If its divisible by 2, divide by 2. 
3. If its divisible by 3, divide by 3. Now the question is, given a positive integer n, find the 
minimum 
number of steps that takes n to 1. 
Cannot apply Greedy! (Why ?) 
Recursive Solution : 
We will define the recurrence relation as 
solve(n): 
if n = 1 
ans = 0 
if n > 1 
ans = min{1 + solve(n-1), 1 + solve(n/2), 1 + solve(n/3)} 

 
Since we are solving a single sub-problem multiple number of times, T = O(KN)  
 
MINIMUM COIN CHANGE
Given a value N, if we want to make change for N cents, and we have infinite supply of each of 
C = { C1, C2, ... , CM} valued coins, what is the minimum number of coins to make the change? 
Example : 
Input: coins[] = {25, 10, 5}, N = 30 
Output: Minimum 2 coins required 
We can use one coin of 25 cents and one of 5 cents 
Input: coins[] = {9, 6, 5, 1}, N = 13 
Output: Minimum 3 coins required 
We can use one coin of 6 + 6 + 1 cents coins. 
180 
 
 
Dynamic Programming 
Recursive Solution : 
Start the solution with initially sum = N cents and at each iteration find the minimum coins 
required 
by dividing the problem in subproblems where we take {C1, C2, ..., CM} coin and decrease the 
sum N 
by C[i] (depending on the coin we took). Whenever N becomes 0, this means we have a possible 
solution. To find the optimal answer, we return the minimum of all answer for which N became 
0. 
If N == 0, then 0 coins required. 
If N > 0 
minCoins(N , coins[0..m-1]) = min {1 + minCoins(N-coin[i] ,coins[0....m-1])} 
where i varies from 0 to m-1 and coin[i] <= N 
 
 

Maximum profit from sale of wines


Given n wines in a row, with integers denoting the cost of each wine respectively. Each 

year you can sale the first or the last wine in the row. However, the price of wines 

increases over time. Let the initial profits from the wines be P1, P2, P3…Pn. On the Yth 
year, the profit from the ith wine will be Y*Pi. For each year, your task is to print “beg” or 

“end” denoting whether first or last wine should be sold. Also, calculate the maximum 

profit from all the wines. 

 
 
For each endpoint at every function call, we are doing the following: 
Either we take this end point in the solution, increment/decrement the end point index. 
Or we do not take this end point in the solution. 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Problem Statement
You are given a 2-D matrix A of n rows and m columns where A[i][j] denotes the calories burnt. 
Two persons, a boy and a girl, start from two corners of this matrix. The boy starts from cell 
(1,1) and needs to reach cell (n,m). On the other hand, the girl starts from cell (n,1) and needs to 
reach (1,m). The boy can move right and down. The girl can move right and up. As they visit a 
cell, the amount in the cell A[i][j] is added to their total of calories burnt. You have to maximize 
the sum of total calories burnt by both of them under the condition that they shall meet only in 
one cell and the cost of this cell shall not be included in either of their total. 
 

 
 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
SHORTEST COMMON SUPERSEQUENCE OF
TWO STRINGS
A supersequence is defined as the shortest string that has both str1 and str2 as subsequences. 
str1 = “apple”, str2 = “les” 
“apples” 
str1 = “AGGTAB”, str2 = “GXTXAYB” 
“AGGXTXAYB” 
http://www.spoj.com/problems/ADFRUITS/ 
Approach: 
First we will find the LCS of the two strings. 
We will insert the non-LCS characters in the LCS found above in their original order. 
 

 
 

 
 

 
 
MIXTURES
http://www.spoj.com/problems/MIXTURES/
Given n mixtures on a table, where each mixture has one of 100 different colors 
(0 - 99). When mixing two mixtures of color ‘a’ and ‘b’, resulting mixture have the color (a + b) 
mod 100 and amount of smoke generated is a*b. Find the minimum amount of smoke that we 
can get when mixing all mixtures together, given that we can only mix two adjacent mixtures. 
 
The first thing to notice here is that, if we mix mixtures i...j into a single mixture, irrespective of 
the steps taken to achieve this, the final color of the mixture is same and equal to sum(i,j) = 
sum(color(i)..color(j)) mod 100. 
So we define dp(i,j) as the most optimum solution where least amount of smoke is produced 
while mixing the mixtures from i...j into a single mixture. For achieving this, at the previous 
steps, we would have had to combine the two mixtures which are resultants of ranges i...k and 
k+1...j where i <= k <= j.So it’s about splitting the mixture into 2 subsets and each subset into 2 
more subsets and so on such that smoke produced is minimized. Hence the recurrence relation 
will be: 
dp(i,j) = min(k: i <= k < j) {dp(i,k) + dp(k+1,j) + sum(i,k)*sum(k+1,j)} 
 

LONGEST PALINDROME SUBSEQUENCE


Given a sequence of character, find the length of the longest palindromic subsequence in it. 
Ex. if the given sequence is “BBABCBCAB”, then the output should be 7 as “BABCBAB” is the 
longest 
palindromic subsequence in it. 
Note : For given sequence “BBABCBCAB”, subsquence “BBBBB” and “BBCBB” are also 
palindromic subsequnce 
but these are not longest. 
Approach : The naive solution for this problem is to generate all subsequences of the given 
sequence and 
find the longest palindromic subsequence. 
Optimal substructure Property : 
Let X[0..n-1] be the input sequence of length n and L(0, n-1) be the length of the longest 
palindromic 
subsequence of X[0..n-1]. 
i.e. X = A1A2A3 
. . . . . . . . . . . An – 1 An 

Travelling Salesman Problem (TSP)


Given a set of cities and distance between every pair of cities, the problem is to find the shortest 
possible route that visits every city exactly once and returns to the starting point. 
Note the difference between Hamiltonian Cycle and TSP. The Hamiltoninan cycle problem is to 
find if there exist a tour that visits every city exactly once. Here we know that Hamiltonian Tour 
exists (because the graph is complete) and in fact many such tours exist, the problem is to find 
a minimum weight Hamiltonian Cycle. 
 
Euler1 
 
For example, consider the graph shown in figure on right side. A TSP tour in the graph is 
1-2-4-3-1. The cost of the tour is 10+25+30+15 which is 80. 
 
The problem is a famous NP hard problem. There is no polynomial time know solution for this 
problem. 
 
Following are different solutions for the traveling salesman problem. 
 
Naive Solution: 
1) Consider city 1 as the starting and ending point. 
2) Generate all (n-1)! Permutations of cities. 
3) Calculate cost of every permutation and keep track of minimum cost permutation. 
4) Return the permutation with minimum cost. 
 
Time Complexity: Θ(n!) 
 
Dynamic Programming: 
Let the given set of vertices be {1, 2, 3, 4,….n}. Let us consider 1 as starting and ending point of 
output. For every other vertex i (other than 1), we find the minimum cost path with 1 as the 
starting point, i as the ending point and all vertices appearing exactly once. Let the cost of this 
path be cost(i), the cost of corresponding Cycle would be cost(i) + dist(i, 1) where dist(i, 1) is the 
distance from i to 1. Finally, we return the minimum of all [cost(i) + dist(i, 1)] values. This looks 
simple so far. Now the question is how to get cost(i)? 
To calculate cost(i) using Dynamic Programming, we need to have some recursive relation in 
terms of sub-problems. Let us define a term C(S, i) be the cost of the minimum cost path 
visiting each vertex in set S exactly once, starting at 1 and ending at i. 
We start with all subsets of size 2 and calculate C(S, i) for all subsets where S is the subset, then 
we calculate C(S, i) for all subsets S of size 3 and so on. Note that 1 must be present in every 
subset. 
 
If size of S is 2, then S must be {1, i}, 
C(S, i) = dist(1, i)  
Else if size of S is greater than 2. 
C(S, i) = min { C(S-{i}, j) + dis(j, i)} where j belongs to S, j != i and j != 1. 
For a set of size n, we consider n-2 subsets each of size n-1 such that all subsets don’t have nth 
in them. 
Using the above recurrence relation, we can write dynamic programming based solution. There 
are at most O(n*2n) subproblems, and each one takes linear time to solve. The total running 
time is therefore O(n2*2n). The time complexity is much less than O(n!), but still exponential. 
Space required is also exponential. So this approach is also infeasible even for slightly higher 
number of vertices. 
 
Subsets of a given set
 
The problems of this type has some set X. The number of elements in this set is small: less than 
20. The idea of DP solution is to consider all subsets of X as state domain. Often there are 
additional parameters. So generally we have state domain in form (s,a) where s is a subset of X 
and "a" represents additional parameters. 
 
Consider TSP problem as an example. The set of cities X={0, 1, 2, ..., N-1} is used here. State 
domain will have two parameters: s and a. The state (s,a)->R means that R is the shortest path 
from city 0 to city "a" which goes through all the vertices from subset s exactly once. The 
transition is simply adding one city v to the end of path: (s,a)->R turns into (s+{v},v)->R + M[a,v]. 
Here M[i,j] is distance between i-th and j-th city. Any hamiltonian cycle is a path which goes 
through each vertex exactly once plus the edge which closes the cycle, so the answer for TSP 
problem can be computed as min(R[X,a]+M[a,0]) among all vertices "a". 
 
It is very convenient to encode subsets with binary numbers. Look recipe "Representing sets 
with bitfields" for detailed explanation. 
 
The state domain of DP over subsets is usually ordered by set inclusion. Each forward transition 
adds some elements to the current subset, but does not subtract any. So result for each state 
(s,a) depends only on the results of states (t,b) where t is subset of s. If state domain is ordered 
like this, then we can iterate through subsets in lexicographical order of binary masks. Since 
subsets are usually represented with binary integers, we can iterate through all subsets by 
iterating through all integers from 0 to 2^N — 1. For example in TSP problem solution looks like: 
 
 
Often in DP over subsets you have to iterate through all subsets or supersets of a given set s. 
The bruteforce implementation will require O(4^N) time for the whole DP, but it can be easily 
optimized to take O(3^N).  
 

Substrings of a given string

There is a fixed string or a fixed segment. According to the problem definition, it can be broken into 
two pieces, then each of pieces can be again divided into two pieces and so forth until we get 
unit-length strings. And by doing this we need to achieve some goal. 

Classical example of DP over substrings is context-free grammar parsing algorithm. Problems which 
involve putting parentheses to arithmetic expression and problems that ask to optimize the overall 
cost of recursive breaking are often solved by DP over substrings. In this case there are two special 
parameters L and R which represent indices of left and right borders of a given substring. There can 
be some additional parameters, we denote them as "a". So each state is defined by (L,R,a). To 
calculate answer for each state, all the ways to divide substring into two pieces are considered. 
Because of it, states must be iterated through in order or non-decreasing length. Here is the scheme 
of DP over substrings (without additional parameters): 
 
 

InformFriends

We are asked to find assignment man->fact which maximizes the number of facts with constraint 
that everyone must know all the facts. In the optimal assignment people can be divided into 
fact-groups. Each fact-group consists of people who are told the same fact. And each fact-group 
must be able to tell everybody else about the fact. Let's precalculate for each subset of people 
whether they can become a fact-group. The subset can be a fact-group if set of all thier friends 
united with them is the whole set. After possible fact-groups are calculated, we have to determine 
maximal number of non-intersecting fact-groups in the set of people. We can define state domain 
(s)->R where s is subset of people and R is problem answer for them. To determine the answer for 
state s we have to subtract one of its fact-groups. It is a subset of s and forms a fact-group. So we 
can iterate through all subsets of s and try them as fact-groups. 
 

You might also like