Open In App

Minimize cost of placing tiles of dimensions 2 * 1 over a Matrix

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: 

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:

Below is the implementation of the above approach:




// 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 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 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# 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.




<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>

 
 

Output: 
20

 

Time Complexity: O(N)
Auxiliary Space: O(N)


Article Tags :