Open In App
Related Articles

Minimum Cost to cut a board into squares

Improve Article
Improve
Save Article
Save
Like Article
Like

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)

This article is contributed by Utkarsh Trivedi. If you like GeeksforGeeks and would like to contribute, you can also write an article using write.geeksforgeeks.org or mail your article to review-team@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.
Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.
 


Last Updated : 13 Feb, 2023
Like Article
Save Article
Similar Reads
Related Tutorials