0% found this document useful (0 votes)
46 views32 pages

Algorithms and Problem Solving (15B11CI411) : EVEN 2022

The document discusses dynamic programming techniques including memoization (top-down) and tabulation (bottom-up). It provides examples of applying dynamic programming to solve the Fibonacci numbers problem, the 0-1 knapsack problem, and the matrix chain multiplication problem. Dynamic programming breaks down optimization problems into overlapping subproblems and stores solutions to avoid recomputing them, improving efficiency over naive recursive solutions.

Uploaded by

Vivek Garg
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
46 views32 pages

Algorithms and Problem Solving (15B11CI411) : EVEN 2022

The document discusses dynamic programming techniques including memoization (top-down) and tabulation (bottom-up). It provides examples of applying dynamic programming to solve the Fibonacci numbers problem, the 0-1 knapsack problem, and the matrix chain multiplication problem. Dynamic programming breaks down optimization problems into overlapping subproblems and stores solutions to avoid recomputing them, improving efficiency over naive recursive solutions.

Uploaded by

Vivek Garg
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 32

Algorithms and Problem Solving (15B11CI411)

EVEN 2022

Design Technique: Dynamic


Programming

Jaypee Institute of Information Technology (JIIT)


A-10, Sector 62, Noida
Dynamic Programming
• Dynamic programming amounts to breaking down an optimization problem into simpler sub-
problems, and storing the solution to each sub-problem so that each sub-problem is only solved
once.
• Dynamic Programming is mainly used when solutions to the same sub-problems are needed again
and again. It is not useful when there are no common (overlapping) sub-problems.
• There is no point in storing the solutions if they are not needed again. For example, Binary
Search doesn’t have common sub-problems.
Top-Down
• Referred to as Memoization: In Memoization, we cache the results of function calls and return
the cached result if the function is called again with the same inputs. This is a top-down approach,
and it has extensive recursive calls.
Bottom-Up
• Referred to as Dynamic Programming: In Dynamic Programming (Dynamic Tables), where we
store the results of the subproblems in a table and use these results to solve larger subproblems
until we solve the entire problem.
Example: Fibonacci number Recursive calls:
15
Fib (n) = 1; if n = 0
Fib(5)
Fib (n) = 1; if n = 1
Fibonacci (n) = Fibonacci(n-1) + Fibonacci(n-2) 9 14
Fib(4) + Fib(3)
int Fib (int n) 5 8 12 13
{ Fib(3) + Fib(2) Fib(2) + Fib(1)
if (n < 2) 3 4 6 7 10 11
return 1; Fib(2) + Fib(1) Fib(1) + Fib(0) Fib(1) + Fib(0)
return Fib(n-1) + Fib(n-2); 1 2
} Fib(1) + Fib(0)
Recursive calls:
Using Memoization: 15
int dp[10]= {-1,-1…-1}; Fib(5)
9 14
int fib(int n)
{ Fib(4) + Fib(3)
5 12
if (n <= 1) 8 13
return n; Fib(3) + Fib(2) Fib(2) + Fib(1)
int first, second; 3 4 7 10 11
6
if (dp[n - 1] != -1) Fib(2) + Fib(1) Fib(1) + Fib(0) Fib(1) + Fib(0)
first = dp[n - 1]; 1 2
else Fib(1) + Fib(0)
first = fib(n - 1);
if (dp[n - 2] != -1) -1 -1 -1 -1 -1 -1
second = dp[n - 2];
else -1 1 -1 -1 -1 -1
second = fib(n - 2);
0 1 -1 -1 -1 -1
// memoization
return dp[n] = first + second; 0 1 1 -1 -1 -1
}
0 1 1 2 -1 -1

0 1 1 2 3 -1

0 1 1 2 3 5
Recursive calls:
Using Dynamic Programming
Fib(5)
(Tabulation Method)
Fib(4) + Fib(3)
void fib ()
{
result[0] = 1; Fib(3) + Fib(2) Fib(2) + Fib(1)
result[1] = 1;
for (int i = 2; i<n; i++) Fib(2) + Fib(1) Fib(1) + Fib(0) Fib(1) + Fib(0)
result[i] = result[i-1] + result[i-2];
} Fib(1) + Fib(0)

Evaluation:
result[2] = result[1]+result[0]
result[3] = result[2]+result[1]
result[4] = result[3]+result[2]
result[5] = result[4]+result[3]
0-1 Kanpsack problem:
• The maximum value obtained from ‘N’ items is the max of the following two values.
• Maximum value obtained by N-1 items and W weight (excluding Nth item)
• Value of Nth item plus maximum value obtained by N-1 items and (W – weight of the Nth
item) [including Nth item].
• If the weight of the Nth item is greater than ‘W’, then the Nth item cannot be included and Case1 is
the only possibility.

knapSack(5, 3)

Recurssive solution: knapSack(2, 2) knapSack(5, 2)


if (n == 0 || W == 0) return 0; knapSack(0, 1) knapSack(2, 1) knapSack(3, 1) knapSack(5, 1)
if (wt[n - 1] > W) return knapSack(W, wt, val, n - 1);
else knapSack(1, 0) knapSack(2, 0)
knapSack(2, 0) knapSack(3, 0)
return max(val[n – 1] + knapSack(W - wt[n - 1], wt, val, n - 1) knapSack(4, 0) knapSack(5,0)
, knapSack(W, wt, val, n - 1));
Item Weight (kg) Value ($) dp[i][W] 0 1 2 3 4 5
Mirror 2 3 0 0 0 0 0 0 0

Silver nugget 3 4 1 0 0 3 3 3 3
2 0 0 3 4 4 7
Painting 4 5
3 0 0 3 4 5 7
Vase 5 6
4 0 0 3 4 5 7
W=5

dp (i , j) = max {dp( i-1, j ), valuei + dp( i-1 , j – weighti ) }

dp (1,1) = max {dp( 0, 1 ), value1 + dp( 0 , 1- weight1 ) } = 0


dp (1,2) = max {dp( 0, 2 ), value1 + dp( 0 , 2 – weight1 ) } = max {0, 3+ dp(0,0)} = 3
dp (1,3) = max {dp( 0, 3 ), value1 + dp( 0 , 3 – weight1 ) } = max {0, 3+ dp(0,1)} = 3
dp (1,4) = max {dp( 0, 4 ), value1 + dp( 0 , 4 – weight1 ) } = max {0, 3+ dp(0,2)} = 3

dp (3,3) = max {dp( 2, 3 ), value3 + dp( 2 , 3 – weight3 ) } = 4


dp (3,4) = max {dp( 2, 4 ), value3 + dp( 2 , 4 – weight3 ) } = max {5, 0} = 5
dp (3,5) = max {dp( 2, 5 ), value3 + dp( 2 , 5 – weight3 ) } = max {7, 5} = 7

int knapSack(int W, int wt[], int val[], int i, int** dp)
{
// base condition
if (i < 0)
return 0;
if (wt[i] > W) {
// Store the value of function call stack in table before return
dp[i][W] = knapSack(W, wt, val, i - 1, dp);
return dp[i][W];
}
else {
dp[i][W] = max(val[i] + knapSack(W - wt[i], wt, val, i - 1, dp),
knapSack(W, wt, val, i - 1, dp));
// Return value of table after storing
return dp[i][W];
}
}
Matrix Chain Multiplication Problem:

• Given the dimension of a sequence of matrices in an array arr[], where the dimension of the ith matrix
is (arr[i-1] * arr[i]), the task is to find the most efficient way to multiply these matrices together such that
the total number of element multiplications is minimum.
• Example: A1×2, B2×3, C3×4, D4×3 (Let the dimensions are read as p[] = {1, 2, 3, 4, 3})
• Minimum number of multiplications are obtained by putting parenthesis in following way ((AB)C)D.
The minimum is 1*2*3 + 1*3*4 + 1*4*3 = 30
• For a given chain of N matrices, the first partition can be done in N-1 ways.
For the given example: (A)(BCD), (AB)(CD) or (ABC)(D) in these 3 ways.
• So a range [i, j] can be broken into groups like {[i, i], [i+1, j]}, {[i, i+1], [i+1, j]}, . . . , {[i, j-1], [j, j]}.
• Each of the groups can be further partitioned into smaller groups and we can find the total required
multiplications by solving for each of the groups.
• The minimum number of multiplications among all the first partitions is the required answer
Recursive function:

int MatrixChainOrder(int p[], int i, int j)


{
if (i == j)
return 0;
int k, count, mini = INT_MAX;
for (k = i; k < j; k++)
{
count = MatrixChainOrder(p, i, k)
+ MatrixChainOrder(p, k + 1, j)
+ p[i - 1] * p[k] * p[j];

mini = min(count, mini);


}
Dimension of matrix A[i] is p[i-1] x p[i]
// Return minimum count
return mini;
}

Example: int p[] = { 1, 2, 3, 4, 3 };


Using Memoization
• Build a matrix dp[][] of size N*N for memoization.
• Use the same recursive calls:
• When we find a range (i, j) for which the value is already calculated, return the minimum value for that range
(i.e., dp[i][j]).
• Otherwise, perform the recursive calls as mentioned earlier.
• The value stored at dp[0][N-1] is the required answer.
int MCMemoised(int* p, int i, int j) {
if (i == j) { Example: int p[] = { 1, 2, 3, 4, 3 };

return 0; i, j 1 2 3 4
} 1 -1 -1 -1 -1
if (dp[i][j] != -1) {
2 -1 -1 -1 -1
return dp[i][j];
3 -1 -1 -1 -1
}
dp[i][j] = INT_MAX; 4 -1 -1 -1 -1

for (int k = i; k < j; k++) { i, j 1 2 3 4


dp[i][j] = min( dp[3][4] = min(dp[3][4], i, j 1 2 3 4
1 0 -1 -1 inf
dp[i][j], MCMemoised(p, i, k) MCMemoised(p,3,3)+ 1 0 -1 -1 inf
2 -1 0 -1 inf MCMemoised(p,4,4) +
+ MCMemoised(p, k + 1, j) 2 -1 0 -1 inf
3 -1 -1 0 inf p[2] * p[3] * p[4])
+ p[i - 1] * p[k] * p[j]); 3 -1 -1 0 36
4 -1 -1 -1 0 = min(inf, (0+0+36))=36
} 4 -1 -1 -1 0
return dp[i][j];
}
for (int k = i; k < j; k++) {
Example: int p[] = { 1, 2, 3, 4, 3 }; dp[i][j] = min(dp[i][j], MCMemoised(p, i, k)
+ MCMemoised(p, k + 1, j)
+ p[i - 1] * p[k] * p[j]); }
i, j 1 2 3 4
1 0 -1 -1 inf dp[2][3] = min(dp[2][3],
2 -1 0 24 inf MCMemoised(p,2,2)+
MCMemoised(p,3,3) +
3 -1 -1 0 36
p[1] * p[2] * p[3])
4 -1 -1 -1 0 = min(inf, (0+0+24))=24

i, j 1 2 3 4 dp[2][4] = min(dp[2][4],
MCMemoised(p,2,2)+
1 0 -1 -1 inf
MCMemoised(p,3,4) + i, j 1 2 3 4 dp[1][3] = min(dp[1][3],
2 -1 0 24 48 p[1] * p[2] * p[4])
1 0 6 18 inf MCMemoised(p,1,1)+
3 -1 -1 0 36 = min(inf, (0+36+18))=54 MCMemoised(p,2,3) +
dp[2][4] = min(dp[2][4], 2 -1 0 24 24
4 -1 -1 -1 0 p[0] * p[1] * p[3])
MCMemoised(p,2,3)+ 3 -1 -1 0 36 = min(inf, (0+24+8))=32
MCMemoised(p,4,4) + 4 -1 -1 -1 0 dp[1][3] = min(dp[1][3],
p[1] * p[3] * p[4]) MCMemoised(p,1,2)+
i, j 1 2 3 4 = min(54, (24+0+24))=48 MCMemoised(p,3,3) +
1 0 6 -1 inf dp[1][2] = min(dp[1][2], p[0] * p[2] * p[3])
2 -1 0 24 24 MCMemoised(p,1,1)+ = min(32, (6+0+12))=18
3 -1 -1 0 36 MCMemoised(p,2,2) +
p[0] * p[1] * p[2])
4 -1 -1 -1 0
= min(inf, (0+0+6))=6
Example: int p[] = { 1, 2, 3, 4, 3 }; for (int k = i; k < j; k++) {
dp[i][j] = min(dp[i][j], MCMemoised(p, i, k)
+ MCMemoised(p, k + 1, j)
+ p[i - 1] * p[k] * p[j]); }

i, j 1 2 3 4 dp[1][4] = min(dp[1][4],
1 0 6 18 30 MCMemoised(p,1,1)+
MCMemoised(p,2,4) +
2 -1 0 24 24
p[0] * p[1] * p[4])
3 -1 -1 0 36 = min(inf, (0+24+6))=30
4 -1 -1 -1 0 dp[1][4] = min(dp[1][4],
MCMemoised(p,1,2)+
MCMemoised(p,3,4) +
p[0] * p[2] * p[4])
= min(30, (6+36+9))=30
dp[1][4] = min(dp[1][4],
MCMemoised(p,1,3)+
MCMemoised(p,4,4) +
p[0] * p[3] * p[4])
(14)= (13)4 = ((12)3)4 = ((AB)C)D
= min(30, (18+0+12))=30
Using Tabulation
int MatrixChainOrder(int p[], int n) {
• Iterate from L = 2 to n-1 which denotes the length of the range: int dp[n][n], i, j, k, L, q;
• Iterate from i = 1 to n-(L-1): for (i = 1; i < n; i++)
• Find the right end of the range (j) having L matrices. dp [i][i] = 0;
• Iterate from k = i to j-1 which denotes the point of
partition. for (L = 2; L < n; L++)
• Multiply the matrices in range (i, k) and (k, j). {
• This will create two matrices with for (i = 1; i < n - L + 1; i++)
dimensions p[i-1]*p[k] and p[k]*p[j]. {
• No. of multiplications to be performed to multiply j = i + L - 1;
these two matrices X= No. of multiplications dp [i][j] = INT_MAX;
is dp[i][k]+ dp[k+1][j] + p[i-1]*p[k]*p[j].. for (k = i; k <= j - 1; k++)
{
• The value stored at dp[1][N-1] is the required answer
q = dp [i][k]+dp[k + 1][j]+ p[i - 1] * p[k] * p[j];
if (q < dp [i][j])
dp [i][j] = q;
i, j 0 1 2 3 4
}
Example: int p[] = { 1, 2, 3, 4, 3 }; 0 0
}
1 0 }
2 0 return dp[1][n - 1];
3 0 }
4 0
Example: int p[] = { 1, 2, 3, 4, 3 };
int MatrixChainOrder(int p[], int n) {
int dp[n][n], i, j, k, L, q; i, j 0 1 2 3 4
for (i = 1; i < n; i++) 0 0 L=2, i=1, j=2
dp [i][i] = 0; 1 0 6
dp(1,2) = inf
k=1 -> dp(1,2) = min{dp(1,2),
2 0 dp(1,1)+dp(2,2)+p[0]*p[1]*p[2]} =6
for (L = 2; L < n; L++)
3 0
{
4 0
for (i = 1; i < n - L + 1; i++)
{
j = i + L - 1;
dp [i][j] = INT_MAX;
for (k = i; k <= j - 1; k++)
{
q = dp [i][k]+dp[k + 1][j]+ p[i - 1] * p[k] * p[j];
if (q < dp [i][j])
dp [i][j] = q;
}
}
}
return dp[1][n - 1];
}
All pair shortest path problem
• The problem is to find the shortest distances between every pair of vertices in a given edge-
weighted directed Graph.
• Given an n-vertex directed weighted graph, find a shortest path from vertex i to vertex j for
each of the n2 vertex pairs (i,j).
• Can we use Dijkstra’s algorithm?
• Use Dijkstra’s algorithm n times, once with each of the n vertices as the source vertex.
• Time complexity is O(n3) time.
• Works only when no edge has a cost < 0 (No negative edge).
• So let’s define dist(u, v, k) to be the length of the shortest path from u to v that uses at most k edges
• The shortest path between any two vertices has at most V − 1 vertices  need to compute dist(u, v, V
− 1).
• Recursive solution:

• E.g.: dist(2,3,1) = min(dist(2,1,0)+w(13),dist(2,2,0)+w(23),dist(2,3,0)+w(33),dist(2,4,0)+w(43))


= min(2+3, 0+inf, inf+0, inf+inf) = 5
Dynamic Programming: T(n) = O(V^4)
Floyd Warshall Algorithm
• Define dist(u, v, r) to be the length of the shortest path from u to v, where all the intermediate
vertices (if any) are numbered r or less

• Algorithm: T(n) = O(V^3)


dist(i,j,-1) dist(i,j,0)
0 inf -2 Inf 0 inf -2 Inf dist(1,2,0) = min {dist(1,2,-1), dist(1,0,-1) + dist(0,2,-1) =min{3,4-2}
4 0 3 Inf 4 0 2 Inf
inf Inf 0 2 inf Inf 0 2
inf -1 inf 0 inf -1 inf 0 dist(1,3,0) = min {dist(1,3,-1), dist(1,0,-1) + dist(0,3,-1) =min{inf,4+inf}
...

...
dist(i,j,1)
dist(3,0,1) = min {dist(3,0,0), dist(3,1,0) + dist(1,0,0) =min{inf,-1+4}
dist(3,2,1) = min {dist(3,2,0), dist(3,1,0) + dist(1,2,0) =min{inf,-1+2}
0 inf -2 Inf
...
4 0 2 Inf
inf Inf 0 2
3 -1 1 0
dist(i,j,1)

0 inf -2 Inf
4 0 2 Inf
inf Inf 0 2
3 -1 1 0

dist(i,j,2)
...
0 inf -2 0 dist(0,3,2) = min {dist(0,3,1), dist(0,2,1) + dist(2,3,1)} =min{inf,-2+2}
dist(1,3,2) = min {dist(1,3,1), dist(1,2,1) + dist(2,3,1)}=min{inf,2+2}
4 0 2 4
...
inf Inf 0 2
3 -1 1 0

dist(i,j,3)
...
0 -1 -2 0 dist(0,1,3) = min {dist(0,1,2), dist(0,3,2) + dist(3,1,2)} =min{inf,0-1}
4 0 2 4 dist(2,0,3) = min {dist(2,0,2), dist(2,3,2) + dist(3,0,2)} =min{inf,2+3}
dist(2,1,3) = min {dist(2,1,2), dist(2,3,2) + dist(3,1,2)} =min{inf,2-1}
5 1 0 2 ...
3 -1 1 0
Problem: Detect negative-weight cycles in the graph

• To detect negative cycles using the Floyd–Warshall algorithm,


check the distance matrix’s diagonal for a negative number as it
indicates that the graph contains at least one negative cycle.
• The Floyd–Warshall algorithm iteratively revises path lengths 22: dist=0
between all pairs of vertices (i, j), including where i = j. 2132: dist=-1

• Initially, the size of the path (i, i) is zero. A path [i, k…i] can only
improve upon this if it has a length less than zero, i.e., denotes a
negative cycle.
Problem: Find transitive closure of a graph
The transitive closure for a digraph G is a digraph G’ with an
edge (i,j) corresponding to each directed path from i to j in G.
The resultant digraph G’ representation in the form of the adjacency matrix is
called the connectivity matrix.

• In Floyd Warshall Algorithm, check


• Is there a direct edge between the starting vertex and the
ending vertex ? If yes, then update the transitive closure
matrix value as 1.
• For k, any intermediate vertex, is there any edge between the
(starting vertex & k) and (k & ending vertex) ? If yes, then
update the transitive closure matrix value as 1.
• Set Cover Problem: Given a universe U of n elements, a collection of subsets of U say S =
{S1, S2…,Sm} where every subset Si has an associated cost. Find a minimum cost sub-collection
of S that covers all elements of U.
• Example: U = {1,2,3,4,5}, S = {S1,S2,S3}, S1 = {4,1,3}, Cost(S1) = 5, S2 = {2,5}, Cost(S2) = 10, S3 =
{1,4,3,2}, Cost(S3) = 3
• There are two possible set covers {S1, S2} with cost 15 and {S2, S3} with cost 13.
• Minimum cost of set cover is 13 and set cover is {S2, S3}
• Greedy strategy: Let I represents set of elements included so far. Initialize I = {}. Pick the set for
which Cost(Si) / |Si - I| is minimum.

• Say a company needs to buy a certain amount of varied supplies and there are suppliers that
offer various deals for different combinations of materials (Supplier A: 2 tons of steel + 500
tiles for $x; Supplier B: 1 ton of steel + 2000 tiles for $y; etc.). Find the best way to get all the
materials while minimizing cost
• K-Center Problem: Given n cities and distances between every pair of cities,
select k cities to place warehouses (or ATMs or Cloud Server) such that the
maximum distance of a city to a warehouse (or ATM or Cloud Server) is
minimized.
• Example: Place 2 ATMs in 4 cities, such that the maximum distance of a city to an
ATM is minimized.
Greedy Solution:
1) Pick the first center i at random.
2) Select the remaining k-1 centers as follows:
Let's call the already chosen centers c1, c2, c3,... ci. Choose the (i+1)th center by selecting the city that is the
farthest away from the previously chosen centers, i.e., the point p with the maximum Min(dist(p, c1), dist(p, c2),
dist(p, c3), dist(p, c4),.... dist(p, ci)).
• Let i = city 0.
• Maximum of Minimum of all distanced from all the cities to the city 0:
Max(dist(0, 0), dist(1, 0), dist(2, 0), dist(3, 0)) = max(0, 12, 7, 6) = 12.
• Now the city 1 is at the maximum distance(12) from city 0. Therefore next select city 1 as the center.
• We have two centers selected, and hence the greedy algorithm stops here.
• ATM centers are at 0 and 1, with the maximum distance of a city from ATM being 6.
Max(min(dist(0, 0), dist(0,1)), min(dist(1, 0),dist(1,1)),min( dist(2, 0), dist(2,1)), min(dist(3, 0),dist(3,1)))
= max(0, 0, 6, 5) = 6
• Suppose a paper products manufacturer has enough capital to build and manage an additional manufacturing
plant in US in order to meet increased demand in three cities: NY, LA, and Topeka. The company already has
distribution facilities in Denver, Seattle, and St. Louis, and due to limited capital, cannot build an additional
distribution facility. So, they must choose to build their new plant in one of these three locations. Due to
geographic constraints, plants in Denver, Seattle, and St. Louis would have a maximum operating capacity of 400
tons/day, 700 tons/day, and 600 tons/day, respectively. The cost of transporting the products from the plant to
the city is directly proportional, and an outline of the supply, demand, and cost of transportation is shown in the
figure below. Regardless of where the plant is built, the selling price of the product is $100/ton.
• Problem: Given N rods of different lengths. The task is to cut all the rods with some maximum integer
height ‘h’ such that the sum of cut-off lengths of the rod is maximized and must be greater than M. Print
-1 if no such cut is possible.
• Input: N = 7, M = 8, a[] = {1, 2, 3, 5, 4, 7, 6}
• Output: 3
• Rod 1 and 2 are untouched, and rod 3, 4, 5, 6, 7 are cut with the cut-off lengths being (3-3) + (4-3) + (5-3)
+ (7-3) + (6-3) which is equal to 10 which is greater than M = 8.
// a[] is sorted in ascending order a[] = {1, 2, 3, 4, 5, 6, 7} Low=4, high=5
int greedyBSCut(int a[], int M, int N) { greedyBSCut(a,8,7) flag=0, sum=0
int low = 0, high = a[N - 1]; low=0, high=7 mid=4
while (low < high) { flag=0, sum=0 i=6:0
int flag = 0, sum = 0, mid; mid=3 a[6] > 4  sum=3 & sum<8
mid = low + (high - low) / 2; i=6:0 a[5] > 4  sum=5 & sum<8
for (int i = N - 1; i >= 0; i--) { a[6] > 3  sum=4 & sum<8 a[4] > 4  sum=6 & sum<8
if (a[i] > mid) a[5] > 3  sum=7 & sum<8 flag==0  high=4
sum = sum + a[i] – mid; a[4] > 3  sum=9 & sum>=8  flag=1, low=4 low=4, high=4
if (sum >= M) { Low=4, high=7 return 3
flag = 1; flag=0, sum=0
low = mid + 1; mid=5
break;} i=6:0
} a[6] > 5  sum=2 & sum<8
if (flag == 0) a[5] > 5  sum=3 & sum<8
high = mid; flag==0  high=5
}
return low - 1;}
• Problem: Given a paper of size A x B. Task is to cut the paper into squares of any size. Find the
minimum number of squares that can be cut from the paper.
• Example: Given paper is of size 13X29
• Maximum square will be of side 13.
• So we can cut 2 square of size 13 x 13 (29/13 = 2).
• Now remaining paper will have size 3 x 13.
• Similarly we can cut remaining paper by using 4 squares of size 3 x 3 and 3 squares of 1 x 1.
• So minimum 9 squares can be cut from the Paper of size 13 x 29.

• Recursive solution: Assuming we have a rectangle with width is N and height is M.


• if (N == M), so it is a square and nothing need to be done.
• Otherwise, we can divide the rectangle into two smaller one (N – x, M) and (x, M), so it can
be solved recursively.
• Similarly, we can also divide it into (N, M – x) and (N, x)
Dynamic Programming Solution:
(3, 5)
int minimumSquare(int m, int n) {
9= 5+min(10,4) int vertical_min = INT_MAX, horizontal_min = INT_MAX;
(1, 5) + (2, 5) (3, 1) + (3, 4) (3, 2) + (3, 3) // N=11 & M=13 is a special case
if(n==13 && m==11) return 6;
4 = min(--,4) if(m==13 && n==11) return 6;
5 10
(2, 1)+ (2, 4) (2, 2)+ (2, 3) if (m == n)
(1, 1) + (1, 4) (1, 5) + (1, 5) 3
return 1;
8 6
4
(1, 4)+ (1, 4) (1, 3)+ (1, 3) (2, 1)+ (2, 2) if (dp[m][n])
return dp[m][n];
(1, 1) + (1, 3)
3
for (int i = 1;i<= m/2;i++)
(1, 1) + (1, 2) {
2 horizontal_min = min(minimumSquare(i, n) +
minimumSquare(m-i, n), horizontal_min);
(1, 1) + (1, 1) }
for (int j = 1;j<= n/2;j++)
{
vertical_min = min(minimumSquare(m, j) +
minimumSquare(m, n-j), vertical_min);
}

dp[m][n] = min(vertical_min, horizontal_min);


return dp[m][n];
}
• Problem: Given an undirected,un-weighted graph G.
Find all the disjoint paths (paths which don’t have
common edges) from source node to the sink node.
• Hint:
• Create a network-flow from source to sink by
assigning 1-unit weight to each edge
• Apply modified Ford Fulkerson algorithm
• (1-center problem) Minimize the max distance between a facility
and customers.
• An optimal Algorithm:
• 1. Compute the matrix of shortest paths costs for all pairs of
nodes.
• 2. The vertex 1-center is the one with the smallest maximum
value in its row in the matrix.
Problem: You are given n balloons, indexed from 0 to n-1.
Each balloon is painted with a number on it represented by an array nums. You are asked to
burst all the balloons.
If you burst the ith balloon, you will get nums[i - 1] * nums[i] * nums[i + 1] coins.
If i-1 or i+1 goes out of bounds of the array, then treat it as if there is a balloon with a 1 painted
on it. Return the maximum coins you can collect by bursting the balloons wisely.

Input: nums = [3, 1, 5, 8] Output: 167


Explanation: nums = [3,1,5,8] --> [3, 5, 8] --> [3, 8] --> [8] --> []
coins = 3*1*5 + 3*5*8 + 1*3*8 + 1*8*1 = 167

You might also like