Given a matrix M[][] of dimension 2*N, the task is to find the minimum cost to fill the matrix with tiles of dimension 2 * 1 such that the cost of filling a tile is equal to the sum of the matrix element placed in the cells where the tile is placed and the discount is equal to the absolute difference between matrix elements in those cells.
Examples:
Input: M[][] = {{1, 4, 3, 5}, {2, 5, 4, 3}}, N = 4
Output: 18
Explanation:
One of the possible solution is,
Place first tile horizontally at (1, 1) and (1, 2). Cost = (1+4) = 5. Discount = (4 – 1) = 3.
Place second tile horizontally at (1, 3) and (1, 4). Cost = (3+5) = 8. Discount = (5 – 3) = 2.
Place third tile horizontally at (2, 1) and (2, 2). Cost = (2 + 5) = 7. Discount (5 – 2) = 3.
Place fourth tile horizontally at (2, 3) and (2, 4). Cost = (4 + 3) = 7. Discount = (4 – 3) = 1.
Therefore, total cost = (5 + 8 + 7 + 7) = 27. Total discount = (3 + 2 + 3 + 1) = 9. Therefore, actual cost = (27 – 9) = 18, which is the minimum cost in placing all tiles.Input: M[][] = {{7, 5, 1, 3}, {8, 6, 0, 2}}, N = 4
Output : 20
Approach: The idea is to use the Dynamic Programming approach to solve the problem as the problem is similar to Tiling Problem. The given problem can be solved based on the following observations:
- The total cost of placing the tiles in the matrix is equal to the sum of the elements present in the matrix. Therefore, by maximizing the discount, the actual cost will be minimized.
- Here, dp[i] stores the minimum cost after placing 2×1 tiles up to ith column in the matrix.
- The transition from one state to another will be by placing the current tile either vertically at column i or by placing horizontally in columns i and (i – 1) in both rows.
dp[i]= max(dp[i – 1] + abs(M[0][i] – M[1][i]), dp[i – 2] + abs(M[0][i – 1] – M[0][i]) + abs(M[1][i – 1] – M[1][i]))
Follow the steps below to solve the problem:
- Initialize a variable, say origCost, to store total cost in pacing the tiles without a discount.
- Initialize an array, say dp[], for storing the maximum discounted cost in placing tiles up to ith column.
- Find the sum of all the elements in the grid and store it in origCost.
- Traverse over the columns and update dp[i]= max(dp[i – 1] + abs(M[0][i] – M[1][i]), dp[i – 2] + abs(M[0][i – 1] – M[0][i]) + abs(M[1][i – 1] – M[1][i])).
- After completing the above steps, print the value of (origCost – dp[N – 1]) as the result.
Below is the implementation of the above approach:
C++
// C++ program for the above approach #include <bits/stdc++.h> using namespace std; // Function to find the minimum cost // in placing N tiles in a grid M[][] void tile_placing(vector<vector< int > > grid, int N) { // Stores the minimum profit // after placing i tiles int dp[N + 5] = { 0 }; int orig_cost = 0; // Traverse the grid[][] for ( int i = 0; i < 2; i++) { for ( int j = 0; j < N; j++) { // Update the orig_cost orig_cost += grid[i][j]; } } dp[0] = 0; dp[1] = abs (grid[0][0] - grid[1][0]); // Traverse over the range [2, N] for ( int i = 2; i <= N; i++) { // Place tiles horizentally // or vertically dp[i] = max( dp[i - 1] + abs (grid[0][i - 1] - grid[1][i - 1]), dp[i - 2] + abs (grid[0][i - 2] - grid[0][i - 1]) + abs (grid[1][i - 2] - grid[1][i - 1])); } // Print the answer cout << orig_cost - dp[N]; } // Driver Code int32_t main() { vector<vector< int > > M = { { 7, 5, 1, 3 }, { 8, 6, 0, 2 } }; int N = M[0].size(); tile_placing(M, N); return 0; } |
Java
// Java program for the above approach import java.util.*; class GFG { // Function to find the minimum cost // in placing N tiles in a grid M[][] static void tile_placing( int [][] grid, int N) { // Stores the minimum profit // after placing i tiles int dp[] = new int [N + 5 ]; Arrays.fill(dp, 0 ); int orig_cost = 0 ; // Traverse the grid[][] for ( int i = 0 ; i < 2 ; i++) { for ( int j = 0 ; j < N; j++) { // Update the orig_cost orig_cost += grid[i][j]; } } dp[ 0 ] = 0 ; dp[ 1 ] = Math.abs(grid[ 0 ][ 0 ] - grid[ 1 ][ 0 ]); // Traverse over the range [2, N] for ( int i = 2 ; i <= N; i++) { // Place tiles horizentally // or vertically dp[i] = Math.max( dp[i - 1 ] + Math.abs(grid[ 0 ][i - 1 ] - grid[ 1 ][i - 1 ]), dp[i - 2 ] + Math.abs(grid[ 0 ][i - 2 ] - grid[ 0 ][i - 1 ]) + Math.abs(grid[ 1 ][i - 2 ] - grid[ 1 ][i - 1 ])); } // Print the answer System.out.println(orig_cost - dp[N]); } // Driver Code public static void main(String[] args) { int [][] M = { { 7 , 5 , 1 , 3 }, { 8 , 6 , 0 , 2 } }; int N = M[ 0 ].length; tile_placing(M, N); } } // This code is contributed by sanjoy_62. |
Python3
# Python3 program for the above approach # Function to find the minimum cost # in placing N tiles in a grid M[][] def tile_placing(grid, N) : # Stores the minimum profit # after placing i tiles dp = [ 0 ] * (N + 5 ); orig_cost = 0 ; # Traverse the grid[][] for i in range ( 2 ) : for j in range (N) : # Update the orig_cost orig_cost + = grid[i][j]; dp[ 0 ] = 0 ; dp[ 1 ] = abs (grid[ 0 ][ 0 ] - grid[ 1 ][ 0 ]); # Traverse over the range [2, N] for i in range ( 2 , N + 1 ) : # Place tiles horizentally # or vertically dp[i] = max ( dp[i - 1 ] + abs (grid[ 0 ][i - 1 ] - grid[ 1 ][i - 1 ]), dp[i - 2 ] + abs (grid[ 0 ][i - 2 ] - grid[ 0 ][i - 1 ]) + abs (grid[ 1 ][i - 2 ] - grid[ 1 ][i - 1 ])); # Print the answer print (orig_cost - dp[N],end = ""); # Driver Code if __name__ = = "__main__" : M = [ [ 7 , 5 , 1 , 3 ], [ 8 , 6 , 0 , 2 ] ]; N = len (M[ 0 ]); tile_placing(M, N); # This code is contributed by AnkThon |
C#
// C# program for the above approach using System; class GFG { // Function to find the minimum cost // in placing N tiles in a grid M[][] static void tile_placing( int [,] grid, int N) { // Stores the minimum profit // after placing i tiles int [] dp = new int [N + 5]; for ( int i = 0; i < N + 5; i++) { dp[i] = 0; } int orig_cost = 0; // Traverse the grid[][] for ( int i = 0; i < 2; i++) { for ( int j = 0; j < N; j++) { // Update the orig_cost orig_cost += grid[i, j]; } } dp[0] = 0; dp[1] = Math.Abs(grid[0, 0] - grid[1, 0]); // Traverse over the range [2, N] for ( int i = 2; i <= N; i++) { // Place tiles horizentally // or vertically dp[i] = Math.Max( dp[i - 1] + Math.Abs(grid[0, i - 1] - grid[1, i - 1]), dp[i - 2] + Math.Abs(grid[0, i - 2] - grid[0, i - 1]) + Math.Abs(grid[1, i - 2] - grid[1, i - 1])); } // Print the answer Console.Write(orig_cost - dp[N]); } // Driver Code public static void Main() { int [,] M = { { 7, 5, 1, 3 }, { 8, 6, 0, 2 } }; int N = 4; tile_placing(M, N); } } // This code is contributed by code_hunt. |
Javascript
<script> // JavaScript program for the above approach // Function to find the minimum cost // in placing N tiles in a grid M[][] function tile_placing(grid, N) { // Stores the minimum profit // after placing i tiles let dp = new Array(N + 5); dp.fill(0); let orig_cost = 0; // Traverse the grid[][] for (let i = 0; i < 2; i++) { for (let j = 0; j < N; j++) { // Update the orig_cost orig_cost += grid[i][j]; } } dp[0] = 0; dp[1] = Math.abs(grid[0][0] - grid[1][0]); // Traverse over the range [2, N] for (let i = 2; i <= N; i++) { // Place tiles horizentally // or vertically dp[i] = Math.max( dp[i - 1] + Math.abs(grid[0][i - 1] - grid[1][i - 1]), dp[i - 2] + Math.abs(grid[0][i - 2] - grid[0][i - 1]) + Math.abs(grid[1][i - 2] - grid[1][i - 1])); } // Print the answer document.write((orig_cost - dp[N]) + "</br>" ); } let M = [ [ 7, 5, 1, 3 ], [ 8, 6, 0, 2 ] ]; let N = M[0].length; tile_placing(M, N); </script> |
20
Time Complexity: O(N)
Auxiliary Space: O(N)
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!