Minimize cost of placing tiles of dimensions 2 * 1 over a Matrix
Last Updated :
11 Jun, 2021
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++
#include <bits/stdc++.h>
using namespace std;
void tile_placing(vector<vector< int > > grid, int N)
{
int dp[N + 5] = { 0 };
int orig_cost = 0;
for ( int i = 0; i < 2; i++) {
for ( int j = 0; j < N; j++) {
orig_cost += grid[i][j];
}
}
dp[0] = 0;
dp[1] = abs (grid[0][0] - grid[1][0]);
for ( int i = 2; i <= N; i++) {
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]));
}
cout << orig_cost - dp[N];
}
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
import java.util.*;
class GFG
{
static void tile_placing( int [][] grid, int N)
{
int dp[] = new int [N + 5 ];
Arrays.fill(dp, 0 );
int orig_cost = 0 ;
for ( int i = 0 ; i < 2 ; i++) {
for ( int j = 0 ; j < N; j++) {
orig_cost += grid[i][j];
}
}
dp[ 0 ] = 0 ;
dp[ 1 ] = Math.abs(grid[ 0 ][ 0 ] - grid[ 1 ][ 0 ]);
for ( int i = 2 ; i <= N; i++) {
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 ]));
}
System.out.println(orig_cost - dp[N]);
}
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);
}
}
|
Python3
def tile_placing(grid, N) :
dp = [ 0 ] * (N + 5 );
orig_cost = 0 ;
for i in range ( 2 ) :
for j in range (N) :
orig_cost + = grid[i][j];
dp[ 0 ] = 0 ;
dp[ 1 ] = abs (grid[ 0 ][ 0 ] - grid[ 1 ][ 0 ]);
for i in range ( 2 , N + 1 ) :
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 (orig_cost - dp[N],end = "");
if __name__ = = "__main__" :
M = [ [ 7 , 5 , 1 , 3 ], [ 8 , 6 , 0 , 2 ] ];
N = len (M[ 0 ]);
tile_placing(M, N);
|
C#
using System;
class GFG
{
static void tile_placing( int [,] grid, int N)
{
int [] dp = new int [N + 5];
for ( int i = 0; i < N + 5; i++) {
dp[i] = 0;
}
int orig_cost = 0;
for ( int i = 0; i < 2; i++) {
for ( int j = 0; j < N; j++) {
orig_cost += grid[i, j];
}
}
dp[0] = 0;
dp[1] = Math.Abs(grid[0, 0] - grid[1, 0]);
for ( int i = 2; i <= N; i++) {
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]));
}
Console.Write(orig_cost - dp[N]);
}
public static void Main()
{
int [,] M
= { { 7, 5, 1, 3 }, { 8, 6, 0, 2 } };
int N = 4;
tile_placing(M, N);
}
}
|
Javascript
<script>
function tile_placing(grid, N)
{
let dp = new Array(N + 5);
dp.fill(0);
let orig_cost = 0;
for (let i = 0; i < 2; i++) {
for (let j = 0; j < N; j++) {
orig_cost += grid[i][j];
}
}
dp[0] = 0;
dp[1] = Math.abs(grid[0][0] - grid[1][0]);
for (let i = 2; i <= N; i++) {
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]));
}
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>
|
Time Complexity: O(N)
Auxiliary Space: O(N)
Share your thoughts in the comments
Please Login to comment...