Algorithms and Problem Solving (15B11CI411) : EVEN 2022
Algorithms and Problem Solving (15B11CI411) : EVEN 2022
EVEN 2022
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)
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
• 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:
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
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:
...
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
• 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.
• 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.