Open In App

Minimum Cost to cut a board into squares

Improve
Improve
Like Article
Like
Save
Share
Report

A board of length m and width n is given, we need to break this board into m*n squares such that cost of breaking is minimum. cutting cost for each edge will be given for the board. In short, we need to choose such a sequence of cutting such that cost is minimized. 
Examples: 
 

Minimum Cost to cut a board into squares

For above board optimal way to cut into square is:
Total minimum cost in above case is 42. It is 
evaluated using following steps.

Initial Value : Total_cost = 0
Total_cost = Total_cost + edge_cost * total_pieces

Cost 4 Horizontal cut         Cost = 0 + 4*1 = 4
Cost 4 Vertical cut        Cost = 4 + 4*2 = 12
Cost 3 Vertical cut        Cost = 12 + 3*2 = 18
Cost 2 Horizontal cut        Cost = 18 + 2*3 = 24
Cost 2 Vertical cut        Cost = 24 + 2*3 = 30
Cost 1 Horizontal cut        Cost = 30 + 1*4 = 34
Cost 1 Vertical cut        Cost = 34 + 1*4 = 38
Cost 1 Vertical cut        Cost = 38 + 1*4 = 42

Minimum Cost to cut a board into squares using a greedy algorithm:

This problem can be solved by greedy approach . To get minimum cost , the idea is to cut the edge with highest cost first because we have less number of pieces and after every cut the number of pieces increase . As the question stated Total_cost = Total_cost + edge_cost * total_pieces . 

  • At first sort both the array in non-ascending order
  • We keep count of two variables vert(keeps track of vertical pieces) and hzntl(keeps track of horizontal pieces). We will initialize both of them with 1.
  • We will keep track of two pointers starting from 0th  index of both the array 
  • Now we will take the highest cost edge from those pointers and multiply them with the corresponding variable. That is if we cut a horizontal cut we will add (edge_cost*hzntl) and increase vert by 1 and if we cut a vertical cut we will add(edge_cost*vert) and increase hzntl bt 1 .
  • After cutting all the edges we will get the minimum cost

Below is the implementation of the above approach:

C++




//  C++ program to divide a board into m*n squares
#include <bits/stdc++.h>
using namespace std;
 
// method returns minimum cost to break board into
// m*n squares
int minimumCostOfBreaking(int X[], int Y[], int m, int n)
{
    int res = 0;
 
    //  sort the horizontal cost in reverse order
    sort(X, X + m, greater<int>());
 
    //  sort the vertical cost in reverse order
    sort(Y, Y + n, greater<int>());
 
    //  initialize current width as 1
    int hzntl = 1, vert = 1;
 
    //  loop until one or both cost array are processed
    int i = 0, j = 0;
    while (i < m && j < n)
    {
        if (X[i] > Y[j])
        {
            res += X[i] * vert;
 
            //  increase current horizontal part count by 1
            hzntl++;
            i++;
        }
        else
        {
            res += Y[j] * hzntl;
 
            //  increase current vertical part count by 1
            vert++;
            j++;
        }
    }
 
    // loop for horizontal array, if remains
    int total = 0;
    while (i < m)
        total += X[i++];
    res += total * vert;
 
    // loop for vertical array, if remains
    total = 0;
    while (j < n)
        total += Y[j++];
    res += total * hzntl;
 
    return res;
}
 
//  Driver code to test above methods
int main()
{
    int m = 6, n = 4;
    int X[m-1] = {2, 1, 3, 1, 4};
    int Y[n-1] = {4, 1, 2};
    cout << minimumCostOfBreaking(X, Y, m-1, n-1);
    return 0;
}


Java




// Java program to divide a
// board into m*n squares
import java.util.Arrays;
import java.util.Collections;
 
class GFG
{
    // method returns minimum cost to break board into
    // m*n squares
    static int minimumCostOfBreaking(Integer X[], Integer Y[],
                                                 int m, int n)
    {
        int res = 0;
     
        // sort the horizontal cost in reverse order
        Arrays.sort(X, Collections.reverseOrder());
     
        // sort the vertical cost in reverse order
        Arrays.sort(Y, Collections.reverseOrder());
     
        // initialize current width as 1
        int hzntl = 1, vert = 1;
     
        // loop until one or both
        // cost array are processed
        int i = 0, j = 0;
        while (i < m && j < n)
        {
            if (X[i] > Y[j])
            {
                res += X[i] * vert;
     
                // increase current horizontal
                // part count by 1
                hzntl++;
                i++;
            }
            else
            {
                res += Y[j] * hzntl;
     
                // increase current vertical
                // part count by 1
                vert++;
                j++;
            }
        }
     
        // loop for horizontal array,
        // if remains
        int total = 0;
        while (i < m)
            total += X[i++];
        res += total * vert;
     
        // loop for vertical array,
        // if remains
        total = 0;
        while (j < n)
            total += Y[j++];
        res += total * hzntl;
     
        return res;
    }
     
    // Driver program
    public static void main(String arg[])
    {
        int m = 6, n = 4;
        Integer X[] = {2, 1, 3, 1, 4};
        Integer Y[] = {4, 1, 2};
        System.out.print(minimumCostOfBreaking(X, Y, m-1, n-1));
    }
}
 
// This code is contributed by Anant Agarwal.


Python3




# Python program to divide a board into m*n squares
 
# Method returns minimum cost to 
# break board into m*n squares
def minimumCostOfBreaking(X, Y, m, n):
 
    res = 0
 
    # sort the horizontal cost in reverse order
    X.sort(reverse = True)
 
    # sort the vertical cost in reverse order
    Y.sort(reverse = True)
 
    # initialize current width as 1
    hzntl = 1; vert = 1
 
    # loop until one or both
    # cost array are processed
    i = 0; j = 0
    while (i < m and j < n):
     
        if (X[i] > Y[j]):
         
            res += X[i] * vert
 
            # increase current horizontal
            # part count by 1
            hzntl += 1
            i += 1
         
        else:
            res += Y[j] * hzntl
 
            # increase current vertical
            # part count by 1
            vert += 1
            j += 1
 
    # loop for horizontal array, if remains
    total = 0
    while (i < m):
        total += X[i]
        i += 1
    res += total * vert
 
    #loop for vertical array, if remains
    total = 0
    while (j < n):
        total += Y[j]
        j += 1
    res += total * hzntl
 
    return res
     
# Driver program
m = 6; n = 4
X = [2, 1, 3, 1, 4]
Y = [4, 1, 2]
 
print(minimumCostOfBreaking(X, Y, m-1, n-1))
 
 
# This code is contributed by Anant Agarwal.


C#




// C# program to divide a
// board into m*n squares
using System;
 
class GFG
{
    // method returns minimum cost to break board into
    // m*n squares
    static int minimumCostOfBreaking(int[] X, int[] Y,
                                        int m, int n)
    {
        int res = 0;
     
        // sort the horizontal cost in reverse order
        Array.Sort<int>(X, new Comparison<int>(
                (i1, i2) => i2.CompareTo(i1)));
     
        // sort the vertical cost in reverse order
        Array.Sort<int>(Y, new Comparison<int>(
                (i1, i2) => i2.CompareTo(i1)));
     
        // initialize current width as 1
        int hzntl = 1, vert = 1;
     
        // loop until one or both
        // cost array are processed
        int i = 0, j = 0;
        while (i < m && j < n)
        {
            if (X[i] > Y[j])
            {
                res += X[i] * vert;
     
                // increase current horizontal
                // part count by 1
                hzntl++;
                i++;
            }
            else
            {
                res += Y[j] * hzntl;
     
                // increase current vertical
                // part count by 1
                vert++;
                j++;
            }
        }
     
        // loop for horizontal array,
        // if remains
        int total = 0;
        while (i < m)
            total += X[i++];
        res += total * vert;
     
        // loop for vertical array,
        // if remains
        total = 0;
        while (j < n)
            total += Y[j++];
        res += total * hzntl;
     
        return res;
    }
     
    // Driver program
    public static void Main(String []arg)
    {
        int m = 6, n = 4;
        int []X = {2, 1, 3, 1, 4};
        int []Y = {4, 1, 2};
        Console.WriteLine(minimumCostOfBreaking(X, Y, m-1, n-1));
    }
}
 
// This code is contributed by Princi Singh


Javascript




<script>
 
// JavaScript program to divide a
// board into m*n squares
 
    // method returns minimum cost to break board into
    // m*n squares
    function minimumCostOfBreaking(X, Y,  m, n)
    {
        let res = 0;
       
        // sort the horizontal cost in reverse order
        X.sort();
        X.reverse();
       
        // sort the vertical cost in reverse order
        Y.sort();
        Y.reverse();
       
        // initialize current width as 1
        let hzntl = 1, vert = 1;
       
        // loop until one or both
        // cost array are processed
        let i = 0, j = 0;
        while (i < m && j < n)
        {
            if (X[i] > Y[j])
            {
                res += X[i] * vert;
       
                // increase current horizontal
                // part count by 1
                hzntl++;
                i++;
            }
            else
            {
                res += Y[j] * hzntl;
       
                // increase current vertical
                // part count by 1
                vert++;
                j++;
            }
        }
       
        // loop for horizontal array,
        // if remains
        let total = 0;
        while (i < m)
            total += X[i++];
        res += total * vert;
       
        // loop for vertical array,
        // if remains
        total = 0;
        while (j < n)
            total += Y[j++];
        res += total * hzntl;
       
        return res;
    }
       
 
// Driver Code
 
        let m = 6, n = 4;
        let X = [2, 1, 3, 1, 4];
        let Y = [4, 1, 2];
        document.write(minimumCostOfBreaking(X, Y, m-1, n-1));
      
</script>


Output

42

Time Complexity: O(mlogm + nlogn), where n and m are the sizes of the given arrays.
Auxiliary Space: O(1)

 



Last Updated : 13 Feb, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads