Open In App

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

Improve
Improve
Like Article
Like
Save
Share
Report

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>


 
 

Output: 

20

 

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



Last Updated : 11 Jun, 2021
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads