Minimum Cost to cut a board into squares

Last Updated : 18 Aug, 2026

Given a board of dimensions n × m that needs to be divided into 1 × 1 squares. The cost of making cuts is given in two arrays:

  • x[] represents costs of making different vertical cuts from 1 to m-1.
  • y[] represents costs of making different horizontal cuts from 1 to n-1.
  • The cost of a vertical cut is multiplied by the current number of horizontal segments.
  • The cost of a horizontal cut is multiplied by the current number of vertical segments.

Find the minimum total cost required to divide the entire board into 1 × 1 squares.

Examples: 

Input: n = 3, m = 3, x[] = [2, 1], y[] = [4, 3]
Output: 16
Explanation:

2

So, the total cost = 4 + 3 + 6 + 3 = 16.

Input: n = 2, m = 3, x[] = [2, 1], y[] = [3]
Output: 9
Explanation:

file

So, the total cost = 3 + 3 + 3 = 9.

Try It Yourself
redirect icon

[Naive Approach] Try All Permutations - O((n+m)!×(n+m)) Time and O(n+m) Space

The idea is to generate all possible permutations of the given cuts and then calculate the cost for each permutation. Finally, return the minimum cost among them.

Note: This approach is not feasible for larger inputs because the number of permutations grows factorially as (m+n-2)!.
For each permutation, we must calculate the cost in O(m+n) time. Hence, the overall time complexity becomes O((m+n−2)!×(m+n)).

[Expected Approach] Using Greedy Technique - O( n (log n)+m (log m)) Time and O(1) Space

Since every cut increases the number of board pieces, performing an expensive cut later would make it cross more pieces and increase its contribution to the total cost.

At each step, choose the cut with the maximum cost among the remaining horizontal and vertical cuts.

  • Sort both x[] and y[] in ascending order.
  • Initialize hCount = 1 and vCount = 1.
  • Set two pointers at the end of both arrays to process the largest cut costs first.
  • While both arrays have remaining cuts:
  • If x[i] >= y[j], add x[i] × hCount to the answer, increment vCount, and decrement i.
  • Otherwise, add y[j] × vCount to the answer, increment hCount, and decrement j.
  • Process the remaining cuts in x[] using hCount as the multiplier.
  • Process the remaining cuts in y[] using vCount as the multiplier.
  • Return the accumulated cost.
C++
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;

int minCost(int n, int m, vector<int>& x, vector<int>& y) {
    
    // Sort the cutting costs in ascending order
    sort(x.begin(), x.end());
    sort(y.begin(), y.end()); 

    int hCount = 1, vCount = 1; 
    int i = x.size() - 1, j = y.size() - 1; 
    int totalCost = 0;

    while (i >= 0 && j >= 0) {
        
        // Choose the larger cost cut to 
        // minimize future costs
        if (x[i] >= y[j]) {
            totalCost += x[i] * hCount; 
            vCount++;
            i--;
        } 
        else {
            totalCost += y[j] * vCount; 
            hCount++;
            j--;
        }
    }

    // Process remaining vertical cuts
    while (i >= 0) {
        totalCost += x[i] * hCount;
        vCount++;
        i--;
    }

    // Process remaining horizontal cuts
    while (j >= 0) {
        totalCost += y[j] * vCount;
        hCount++;
        j--;
    }

    return totalCost;
}

int main() {
    
    int n = 3, m = 3;
    vector<int> x = {2, 1};
    vector<int> y = {4, 3};

    cout << minCost(n, m, x, y) << endl;
    return 0;
}
Java
import java.util.Arrays;

class GfG {
    
    public static int minCost(int n, int m, int[] x, int[] y) {
        
        // Sort the cutting costs in ascending order
        Arrays.sort(x);
        Arrays.sort(y); 

        int hCount = 1, vCount = 1; 
        int i = x.length - 1, j = y.length - 1; 
        int totalCost = 0;
        while (i >= 0 && j >= 0) {
            
            // Choose the larger cost cut to 
            // minimize future costs
            if (x[i] >= y[j]) {
                totalCost += x[i] * hCount; 
                vCount++;
                i--;
            } 
            else {
                totalCost += y[j] * vCount; 
                hCount++;
                j--;
            }
        }

        // Process remaining vertical cuts
        while (i >= 0) {
            totalCost += x[i] * hCount;
            vCount++;
            i--;
        }

        // Process remaining horizontal cuts
        while (j >= 0) {
            totalCost += y[j] * vCount;
            hCount++;
            j--;
        }

        return totalCost;
    }

    public static void main(String[] args) {
        
        int n = 3,m = 3;
        int[] x = {2, 1};
        int[] y = {4, 3};

        System.out.println(minCost(n, m, x, y));
    }
}
Python
def minCost(n,m, x, y):
    
    # Sort the cutting costs in ascending order
    x.sort()
    y.sort()

    hCount, vCount = 1, 1
    i, j = len(x) - 1, len(y) - 1
    totalCost = 0
    while i >= 0 and j >= 0:
        
        # Choose the larger cost cut to 
        # minimize future costs
        if x[i] >= y[j]:
            totalCost += x[i] * hCount
            vCount += 1
            i -= 1
        else:
            totalCost += y[j] * vCount
            hCount += 1
            j -= 1

    # Process remaining vertical cuts
    while i >= 0:
        totalCost += x[i] * hCount
        vCount += 1
        i -= 1

    # Process remaining horizontal cuts
    while j >= 0:
        totalCost += y[j] * vCount
        hCount += 1
        j -= 1

    return totalCost

if __name__ == "__main__":
    
    n,m = 3, 3
    x = [2, 1]
    y = [4, 3]

    print(minCost(n,m,x, y))
C#
using System;

class GfG {

    public static int minCost(int n, int m, int[] x, int[] y) {
        
        // Sort the cutting costs in ascending order
        Array.Sort(x);
        Array.Sort(y);

        int hCount = 1, vCount = 1;
        int i = x.Length - 1, j = y.Length - 1;
        int totalCost = 0;

        // Process the cuts in greedy manner
        while (i >= 0 && j >= 0) {
            
            // Choose the larger cost cut to 
            // minimize future costs
            if (x[i] >= y[j]) {
                totalCost += x[i] * hCount;
                vCount++;
                i--;
            }
            else {
                totalCost += y[j] * vCount;
                hCount++;
                j--;
            }
        }

        // Process remaining vertical cuts
        while (i >= 0) {
            totalCost += x[i] * hCount;
            vCount++;
            i--;
        }

        // Process remaining horizontal cuts
        while (j >= 0) {
            totalCost += y[j] * vCount;
            hCount++;
            j--;
        }

        return totalCost;
    }
    
    public static void Main() {
        
        int n=3,m=3;
        int[] x = {2, 1};
        int[] y = {4,3};

        Console.WriteLine(minCost(n,m, x, y));
    }
}
JavaScript
function minCost( n,m, x, y) {
    
    // Sort the cutting costs in ascending order
    x.sort((a, b) => a - b);
    y.sort((a, b) => a - b);

    let hCount = 1, vCount = 1;
    let i = x.length - 1, j = y.length - 1;
    let totalCost = 0;

    while (i >= 0 && j >= 0) {
        
        // Choose the larger cost cut to 
        // minimize future costs
        if (x[i] >= y[j]) {
            totalCost += x[i] * hCount;
            vCount++;
            i--;
        } 
        else {
            totalCost += y[j] * vCount;
            hCount++;
            j--;
        }
    }

    // Process remaining vertical cuts
    while (i >= 0) {
        totalCost += x[i] * hCount;
        vCount++;
        i--;
    }

    // Process remaining horizontal cuts
    while (j >= 0) {
        totalCost += y[j] * vCount;
        hCount++;
        j--;
    }

    return totalCost;
}

// Driver Code
let n = 3,m = 3;
let x = [2, 1];
let y = [4, 3];

console.log(minCost(n,m, x, y));

Output
16
Comment