You are given a set of n types of rectangular 3-D boxes, where the i^th box has height h(i), width w(i) and depth d(i) (all real numbers). You want to create a stack of boxes which is as tall as possible, but you can only stack a box on top of another box if the dimensions of the 2-D base of the lower box are each strictly larger than those of the 2-D base of the higher box. Of course, you can rotate a box so that any side functions as its base. It is also allowable to use multiple instances of the same type of box.Â
Source: http://people.csail.mit.edu/bdean/6.046/dp/. The link also has a video for an explanation of the solution.
Â
Â
The Box Stacking problem is a variation of LIS problem. We need to build a maximum height stack.Â
Following are the key points to note in the problem statement:Â
1) A box can be placed on top of another box only if both width and depth of the upper placed box are smaller than width and depth of the lower box respectively.Â
2) We can rotate boxes such that width is smaller than depth. For example, if there is a box with dimensions {1x2x3} where 1 is height, 2×3 is base, then there can be three possibilities, {1x2x3}, {2x1x3} and {3x1x2}Â
3) We can use multiple instances of boxes. What it means is, we can have two different rotations of a box as part of our maximum height stack.
Following is the solution based on DP solution of LIS problem.
Method 1 : dynamic programming using tabulation
1) Generate all 3 rotations of all boxes. The size of rotation array becomes 3 times the size of the original array. For simplicity, we consider width as always smaller than or equal to depth.Â
2) Sort the above generated 3n boxes in decreasing order of base area.
3) After sorting the boxes, the problem is same as LIS with following optimal substructure property.Â
MSH(i) = Maximum possible Stack Height with box i at top of stackÂ
MSH(i) = { Max ( MSH(j) ) + height(i) } where j < i and width(j) > width(i) and depth(j) > depth(i).Â
If there is no such j then MSH(i) = height(i)
4) To get overall maximum height, we return max(MSH(i)) where 0 < i < n
Following is the implementation of the above solution.Â
Â
C++
/* Dynamic Programming implementation of Box Stacking problem */ #include<stdio.h> #include<stdlib.h> Â
/* Representation of a box */ struct Box {   // h --> height, w --> width, d --> depth   int h, w, d; // for simplicity of solution, always keep w <= d }; Â
// A utility function to get minimum of two integers int min ( int x, int y) { return (x < y)? x : y; } Â
// A utility function to get maximum of two integers int max ( int x, int y) { return (x > y)? x : y; } Â
/* Following function is needed for library function qsort(). We    use qsort() to sort boxes in decreasing order of base area.    Refer following link for help of qsort() and compare() int compare ( const void *a, const void * b) {     return ( (*(Box *)b).d * (*(Box *)b).w ) -            ( (*(Box *)a).d * (*(Box *)a).w ); } Â
/* Returns the height of the tallest stack that can be    formed with give type of boxes */ int maxStackHeight( Box arr[], int n ) {    /* Create an array of all rotations of given boxes       For example, for a box {1, 2, 3}, we consider three       instances{{1, 2, 3}, {2, 1, 3}, {3, 1, 2}} */    Box rot[3*n];    int index = 0;    for ( int i = 0; i < n; i++)    {       // Copy the original box       rot[index].h = arr[i].h;       rot[index].d = max(arr[i].d, arr[i].w);       rot[index].w = min(arr[i].d, arr[i].w);       index++; Â
      // First rotation of box       rot[index].h = arr[i].w;       rot[index].d = max(arr[i].h, arr[i].d);       rot[index].w = min(arr[i].h, arr[i].d);       index++; Â
      // Second rotation of box       rot[index].h = arr[i].d;       rot[index].d = max(arr[i].h, arr[i].w);       rot[index].w = min(arr[i].h, arr[i].w);       index++;    } Â
   // Now the number of boxes is 3n    n = 3*n; Â
   /* Sort the array 'rot[]' in non-increasing order       of base area */    qsort (rot, n, sizeof (rot[0]), compare); Â
   // Uncomment following two lines to print all rotations    // for (int i = 0; i < n; i++ )    //   printf("%d x %d x %d\n", rot[i].h, rot[i].w, rot[i].d); Â
   /* Initialize msh values for all indexes       msh[i] --> Maximum possible Stack Height with box i on top */    int msh[n];    for ( int i = 0; i < n; i++ )       msh[i] = rot[i].h; Â
   /* Compute optimized msh values in bottom up manner */    for ( int i = 1; i < n; i++ )       for ( int j = 0; j < i; j++ )          if ( rot[i].w < rot[j].w &&               rot[i].d < rot[j].d &&               msh[i] < msh[j] + rot[i].h             )          {               msh[i] = msh[j] + rot[i].h;          } Â
Â
   /* Pick maximum of all msh values */    int max = -1;    for ( int i = 0; i < n; i++ )       if ( max < msh[i] )          max = msh[i]; Â
   return max; } Â
/* Driver program to test above function */ int main() { Â Â Box arr[] = { {4, 6, 7}, {1, 2, 3}, {4, 5, 6}, {10, 12, 32} }; Â Â int n = sizeof (arr)/ sizeof (arr[0]); Â
  printf ( "The maximum possible height of stack is %d\n" ,          maxStackHeight (arr, n) ); Â
  return 0; } |
Java
/* Dynamic Programming implementation of Box Stacking problem in Java*/ import java.util.*; Â
public class GFG {          /* Representation of a box */     static class Box implements Comparable<Box>{              // h --> height, w --> width,         // d --> depth         int h, w, d, area;                  // for simplicity of solution,         // always keep w <= d Â
        /*Constructor to initialise object*/         public Box( int h, int w, int d) {             this .h = h;             this .w = w;             this .d = d;         }                  /*To sort the box array on the basis         of area in decreasing order of area */         @Override         public int compareTo(Box o) {             return o.area- this .area;         }     } Â
    /* Returns the height of the tallest     stack that can be formed with give     type of boxes */     static int maxStackHeight( Box arr[], int n){                  Box[] rot = new Box[n* 3 ];                  /* New Array of boxes is created -         considering all 3 possible rotations,         with width always greater than equal         to width */         for ( int i = 0 ;i < n;i++){             Box box = arr[i];                          /* Original Box*/             rot[ 3 *i] = new Box(box.h, Math.max(box.w,box.d),                                     Math.min(box.w,box.d));                          /* First rotation of box*/             rot[ 3 *i + 1 ] = new Box(box.w, Math.max(box.h,box.d),                                        Math.min(box.h,box.d));                          /* Second rotation of box*/             rot[ 3 *i + 2 ] = new Box(box.d, Math.max(box.w,box.h),                                        Math.min(box.w,box.h));         }                  /* Calculating base area of         each of the boxes.*/         for ( int i = 0 ; i < rot.length; i++)             rot[i].area = rot[i].w * rot[i].d;                  /* Sorting the Boxes on the basis         of Area in non Increasing order.*/         Arrays.sort(rot);                  int count = 3 * n;                  /* Initialize msh values for all         indexes         msh[i] --> Maximum possible Stack Height                    with box i on top */         int []msh = new int [count];         for ( int i = 0 ; i < count; i++ )             msh[i] = rot[i].h;                  /* Computing optimized msh[]         values in bottom up manner */         for ( int i = 0 ; i < count; i++){             msh[i] = 0 ;             Box box = rot[i];             int val = 0 ;                          for ( int j = 0 ; j < i; j++){                 Box prevBox = rot[j];                 if (box.w < prevBox.w && box.d < prevBox.d){                     val = Math.max(val, msh[j]);                 }             }             msh[i] = val + box.h;         }                  int max = - 1 ;                  /* Pick maximum of all msh values */         for ( int i = 0 ; i < count; i++){             max = Math.max(max, msh[i]);         }                  return max;     }          /* Driver program to test above function */     public static void main(String[] args) {                  Box[] arr = new Box[ 4 ];         arr[ 0 ] = new Box( 4 , 6 , 7 );         arr[ 1 ] = new Box( 1 , 2 , 3 );         arr[ 2 ] = new Box( 4 , 5 , 6 );         arr[ 3 ] = new Box( 10 , 12 , 32 );                  System.out.println( "The maximum possible " +                            "height of stack is " +                            maxStackHeight(arr, 4 ));     } } Â
// This code is contributed by Divyam |
Python3
# Dynamic Programming implementation # of Box Stacking problem class Box:          # Representation of a box     def __init__( self , h, w, d):         self .h = h         self .w = w         self .d = d Â
    def __lt__( self , other):         return self .d * self .w < other.d * other.w Â
def maxStackHeight(arr, n): Â
    # Create an array of all rotations of     # given boxes. For example, for a box {1, 2, 3},     # we consider three instances{{1, 2, 3},     # {2, 1, 3}, {3, 1, 2}}     rot = [Box( 0 , 0 , 0 ) for _ in range ( 3 * n)]     index = 0 Â
    for i in range (n): Â
        # Copy the original box         rot[index].h = arr[i].h         rot[index].d = max (arr[i].d, arr[i].w)         rot[index].w = min (arr[i].d, arr[i].w)         index + = 1 Â
        # First rotation of the box         rot[index].h = arr[i].w         rot[index].d = max (arr[i].h, arr[i].d)         rot[index].w = min (arr[i].h, arr[i].d)         index + = 1 Â
        # Second rotation of the box         rot[index].h = arr[i].d         rot[index].d = max (arr[i].h, arr[i].w)         rot[index].w = min (arr[i].h, arr[i].w)         index + = 1 Â
    # Now the number of boxes is 3n     n * = 3 Â
    # Sort the array 'rot[]' in non-increasing     # order of base area     rot.sort(reverse = True ) Â
    # Uncomment following two lines to print     # all rotations     # for i in range(n):     #    print(rot[i].h, 'x', rot[i].w, 'x', rot[i].d) Â
    # Initialize msh values for all indexes     # msh[i] --> Maximum possible Stack Height     # with box i on top     msh = [ 0 ] * n Â
    for i in range (n):         msh[i] = rot[i].h Â
    # Compute optimized msh values     # in bottom up manner     for i in range ( 1 , n):         for j in range ( 0 , i):             if (rot[i].w < rot[j].w and                 rot[i].d < rot[j].d):                 if msh[i] < msh[j] + rot[i].h:                     msh[i] = msh[j] + rot[i].h Â
    maxm = - 1     for i in range (n):         maxm = max (maxm, msh[i]) Â
    return maxm Â
# Driver Code if __name__ = = "__main__" : Â Â Â Â arr = [Box( 4 , 6 , 7 ), Box( 1 , 2 , 3 ), Â Â Â Â Â Â Â Â Â Â Â Box( 4 , 5 , 6 ), Box( 10 , 12 , 32 )] Â Â Â Â n = len (arr) Â Â Â Â print ( "The maximum possible height of stack is" , Â Â Â Â Â Â Â Â Â Â Â maxStackHeight(arr, n)) Â
# This code is contributed by vibhu4agarwal |
C#
using System; Â
class Box { Â Â Â Â public int h, w, d, area; Â Â Â Â public Box( int h, int w, int d) Â Â Â Â { Â Â Â Â Â Â Â Â this .h = h; Â Â Â Â Â Â Â Â this .w = w; Â Â Â Â Â Â Â Â this .d = d; Â Â Â Â } Â
    public bool IsSmallerThan(Box other)     {         return this .w * this .d < other.w * other.d;     } } Â
class GFG { Â Â Â Â public static int MaxStackHeight(Box[] arr, int n) Â Â Â Â { // Create an array of all rotations of // given boxes. For example, for a box {1, 2, 3}, // we consider three instances{{1, 2, 3}, // {2, 1, 3}, {3, 1, 2}} Â Â Â Â Â Â Â Â Box[] rot = new Box[3 * n]; Â
        for ( int i = 0; i < n; i++)         {             Box box = arr[i];             // Copy the original box             rot[3 * i] = new Box(box.h, Math.Max(box.w, box.d), Math.Min(box.w, box.d)); Â
            // First rotation of the box             rot[3 * i + 1] = new Box(box.w, Math.Max(box.h, box.d), Math.Min(box.h, box.d)); Â
            // Second rotation of the box             rot[3 * i + 2] = new Box(box.d, Math.Max(box.w, box.h), Math.Min(box.h, box.w));         } Â
        // Calculating base area ofeach of the boxes         for ( int i = 0; i < 3*n; i++)             rot[i].area = rot[i].w * rot[i].d; Â
        // Sort the array 'rot[]' in non-increasing         // order of base area         Array.Sort(rot, (a, b) => b.IsSmallerThan(a) ? -1 : 1); Â
        int count = 3 * n; Â
        // Initialize msh values for all indexes         // msh[i] --> Maximum possible Stack Height         // with box i on top         int [] msh = new int [count]; Â
        for ( int i = 0; i < count; i++)             msh[i] = rot[i].h; Â
        // Compute optimized msh values         // in bottom up manner         for ( int i = 0; i < count; i++)         {             msh[i] = 0;             Box box = rot[i];             int val = 0; Â
            for ( int j = 0; j < i; j++)             {                 Box prevBox = rot[j];                 if (box.w < prevBox.w && box.d < prevBox.d)                 {                     val = Math.Max(val, msh[j]);                 }             }             msh[i] = val + box.h;         } Â
        int max = -1;         for ( int i = 0; i < count; i++)         {             max = Math.Max(max, msh[i]);         } Â
        return max;     } Â
    public static void Main()     {         Box[] arr = new Box[4];         arr[0] = new Box(4, 6, 7);         arr[1] = new Box(1, 2, 3);         arr[2] = new Box(4, 5, 6);         arr[3] = new Box(10, 12, 32); Â
        Console.WriteLine( "The maximum possible " + "height of stack is " + MaxStackHeight(arr, 4));     } } |
Javascript
// Definition of a Box class Box {   constructor(h, w, d) {     this .h = h; // height     this .w = w; // width     this .d = d; // depth   } } Â
// Utility function to get the minimum of two integers function min(a, b) { Â Â return a < b ? a : b; } Â
// Utility function to get the maximum of two integers function max(a, b) { Â Â return a > b ? a : b; } Â
// Function to compare two boxes based on their base area function compare(box1, box2) { Â Â return box2.w * box2.d - box1.w * box1.d; } Â
// Function to find the maximum height of a stack of boxes function maxStackHeight(boxes) {   // Create an array of all rotations of the boxes   const rotations = [];   for (let i = 0; i < boxes.length; i++) {     const box = boxes[i];     // Original orientation     rotations.push( new Box(box.h, max(box.w, box.d), min(box.w, box.d)));     // First rotation     rotations.push( new Box(box.w, max(box.h, box.d), min(box.h, box.d)));     // Second rotation     rotations.push( new Box(box.d, max(box.h, box.w), min(box.h, box.w)));   } Â
  // Sort the rotations in non-increasing order of their base area   rotations.sort(compare); Â
  // Initialize an array to store the maximum stack height for each box   const maxStackHeight = new Array(rotations.length).fill(0);   for (let i = 0; i < rotations.length; i++) {     maxStackHeight[i] = rotations[i].h;   } Â
  // Compute the maximum stack height for each box in bottom-up manner   for (let i = 1; i < rotations.length; i++) {     for (let j = 0; j < i; j++) {       if (rotations[i].w < rotations[j].w && rotations[i].d < rotations[j].d) {         maxStackHeight[i] = max(maxStackHeight[i], maxStackHeight[j] + rotations[i].h);       }     }   } Â
  // Find the maximum stack height   let maxHeight = 0;   for (let i = 0; i < rotations.length; i++) {     if (maxHeight < maxStackHeight[i]) {       maxHeight = maxStackHeight[i];     }   } Â
  return maxHeight; } Â
// Example usage const boxes = [ Â Â new Box(4, 6, 7), Â Â new Box(1, 2, 3), Â Â new Box(4, 5, 6), Â Â new Box(10, 12, 32), ]; const ans = maxStackHeight(boxes); console.log(ans); // Output: 60 |
The maximum possible height of stack is 60
In the above program, given input boxes are {4, 6, 7}, {1, 2, 3}, {4, 5, 6}, {10, 12, 32}. Following are all rotations of the boxes in decreasing order of base area.Â
10 x 12 x 32 12 x 10 x 32 32 x 10 x 12 4 x 6 x 7 4 x 5 x 6 6 x 4 x 7 5 x 4 x 6 7 x 4 x 6 6 x 4 x 5 1 x 2 x 3 2 x 1 x 3 3 x 1 x 2
The height 60 is obtained by boxes { {3, 1, 2}, {1, 2, 3}, {6, 4, 5}, {4, 5, 6}, {4, 6, 7}, {32, 10, 12}, {10, 12, 32}}
Time Complexity: O(n^2)Â
Auxiliary Space: O(n), since n extra space has been taken.
Method 2 : dynamic programming using memoization (top-down)
C++
/* Dynamic Programming top-down implementation of Box  * Stacking problem */ #include <bits/stdc++.h> using namespace std; Â
/* Representation of a box */ class Box { public : Â Â Â Â int length; Â Â Â Â int width; Â Â Â Â int height; }; Â
// dp array int dp[303]; Â
/*     boxes -> vector of Box     bottom_box_index -> index of the bottom box     index -> index of current box */ /* NOTE: we can use only one variable in place of bottom_box_index and index      but it has been avoided to make it simple */ int findMaxHeight(vector<Box>& boxes, int bottom_box_index, int index) { Â
    // base case     if (index < 0)         return 0; Â
    if (dp[index] != -1)         return dp[index]; Â
    int maximumHeight = 0; Â
    // recurse     for ( int i = index; i >= 0; i--) { Â
        // if there is no bottom box         if (bottom_box_index == -1 Â
            // or if length & width of new box is < that of             // bottom box             || (boxes[i].length                     < boxes[bottom_box_index].length                 && boxes[i].width                        < boxes[bottom_box_index].width)) Â
            maximumHeight                 = max(maximumHeight,                       findMaxHeight(boxes, i, i - 1)                           + boxes[i].height);     } Â
    return dp[index] = maximumHeight; } Â
/* wrapper function for recursive calls which Returns the height of the tallest stack that can be formed with give type of boxes */ int maxStackHeight( int height[], int width[], int length[],                    int types) {     // creating a vector of type Box class     vector<Box> boxes; Â
    // Initialize dp array with -1     memset (dp, -1, sizeof (dp)); Â
    Box box; Â
    /* Create an array of all rotations of given boxes     For example, for a box {1, 2, 3}, we consider three     instances{{1, 2, 3}, {2, 1, 3}, {3, 1, 2}} */     for ( int i = 0; i < types; i++) { Â
        // copy original box         box.height = height[i];         box.length = max(length[i], width[i]);         box.width = min(length[i], width[i]); Â
        boxes.push_back(box); Â
        // First rotation of box         box.height = width[i];         box.length = max(length[i], height[i]);         box.width = min(length[i], height[i]); Â
        boxes.push_back(box); Â
        // Second rotation of box         box.height = length[i];         box.length = max(width[i], height[i]);         box.width = min(width[i], height[i]); Â
        boxes.push_back(box);     } Â
    // sort by area in ascending order .. because we will be dealing with this vector in reverse     sort(boxes.begin(), boxes.end(), [](Box b1, Box b2) {         // if area of box1 < area of box2         return (b1.length * b1.width)                < (b2.length * b2.width);     });       // Uncomment following two lines to print all rotations     //for (int i = boxes.size() - 1; i >= 0; i-- )    //  printf("%d x %d x %d\n", boxes[i].length, boxes[i].width, boxes[i].height); Â
    return findMaxHeight(boxes, -1, boxes.size() - 1); } Â
int main() { Â
    // where length, width and height of a particular box     // are at ith index of the following arrays     int length[] = { 4, 1, 4, 10 };     int width[] = { 6, 2, 5, 12 };     int height[] = { 7, 3, 6, 32 }; Â
    int n = sizeof (length) / sizeof (length[0]); Â
    printf ( "The maximum possible height of stack is %d\n" ,            maxStackHeight(height, length, width, n)); Â
    return 0; } |
Java
import java.util.Arrays; Â
public class BoxStacking { Â Â Â Â static class Box implements Comparable<Box> { Â Â Â Â Â Â Â Â int length; Â Â Â Â Â Â Â Â int width; Â Â Â Â Â Â Â Â int height; Â
        public Box( int length, int width, int height) {             this .length = length;             this .width = width;             this .height = height;         } Â
        public int compareTo(Box b) {             return Integer.compare( this .length * this .width, b.length * b.width);         }     } Â
    public static int maxStackHeight( int [] length, int [] width, int [] height) {         int n = length.length;         Box[] boxes = new Box[ 3 * n]; Â
        int k = 0 ;         for ( int i = 0 ; i < n; i++) {             boxes[k++] = new Box(length[i], width[i], height[i]);             boxes[k++] = new Box(width[i], height[i], length[i]);             boxes[k++] = new Box(height[i], length[i], width[i]);         } Â
        Arrays.sort(boxes); Â
        int [] dp = new int [ 3 * n];         int maxHeight = 0 ; Â
        for ( int i = k - 1 ; i >= 0 ; i--) {             dp[i] = boxes[i].height;             for ( int j = i + 1 ; j < k; j++) {                 if (boxes[i].length < boxes[j].length                         && boxes[i].width < boxes[j].width) {                     dp[i] = Math.max(dp[i], boxes[i].height + dp[j]);                 }             } Â
            maxHeight = Math.max(maxHeight, dp[i]);         } Â
        return maxHeight;     } Â
    public static void main(String[] args) {         int [] length = { 4 , 1 , 4 , 10 };         int [] width = { 6 , 2 , 5 , 12 };         int [] height = { 7 , 3 , 6 , 32 }; Â
        System.out.println( "The maximum possible height of stack is "                 + maxStackHeight(length, width, height));     } } // This code contributed SRJ |
Python3
# Dynamic Programming top-down implementation of Box # Stacking problem Â
class Box:     def __init__( self , length, width, height):         self .length = length         self .width = width         self .height = height Â
# dp array dp = [ - 1 ] * 303 Â
def findMaxHeight(boxes, bottom_box_index, index): Â
    # base case     if index < 0 :         return 0 Â
    if dp[index] ! = - 1 :         return dp[index] Â
    maximumHeight = 0 Â
    # recurse     for i in range (index, - 1 , - 1 ): Â
        # if there is no bottom box         if bottom_box_index = = - 1 or (boxes[i].length < boxes[bottom_box_index].length             and boxes[i].width < boxes[bottom_box_index].width): Â
            maximumHeight = max (maximumHeight, findMaxHeight(boxes, i, i - 1 ) + boxes[i].height) Â
    dp[index] = maximumHeight     return maximumHeight Â
# Returns the height of the tallest stack that can be # formed with give type of boxes def maxStackHeight(height, width, length, types): Â
    # creating a vector of type Box class     boxes = [] Â
    # Initialize dp array with -1     dp[:] = [ - 1 ] * 303 Â
    # Create an array of all rotations of given boxes     # For example, for a box {1, 2, 3}, we consider three     # instances{{1, 2, 3}, {2, 1, 3}, {3, 1, 2}}     for i in range (types): Â
        # copy original box         box = Box(length[i], max (length[i], width[i]), min (length[i], width[i]))         boxes.append(box) Â
        # First rotation of box         box = Box(width[i], max (length[i], height[i]), min (length[i], height[i]))         boxes.append(box) Â
        # Second rotation of box         box = Box(length[i], max (width[i], height[i]), min (width[i], height[i]))         boxes.append(box) Â
    # sort by area in ascending order .. because we will be dealing with this vector in reverse     boxes.sort(key = lambda box : (box.length * box.width)) Â
    # Uncomment following two lines to print all rotations     #for (int i = boxes.size() - 1; i >= 0; i-- )     #  printf("%d x %d x %d\n", boxes[i].length, boxes[i].width, boxes[i].height); Â
    return findMaxHeight(boxes, - 1 , len (boxes) - 1 ) Â
# where length, width and height of a particular box # are at ith index of the following arrays length = [ 4 , 1 , 4 , 10 ] width = [ 6 , 2 , 5 , 12 ] height = [ 7 , 3 , 6 , 32 ] Â
types = len (length) Â
print ( "The maximum possible height of stack is" , maxStackHeight(height, length, width, types)) Â
# This code is contributed b factworx412 |
Javascript
class Box { Â Â Â Â Â Â Â constructor(length, width, height) { Â Â Â Â Â Â Â Â Â this .length = length; Â Â Â Â Â Â Â Â Â this .width = width; Â Â Â Â Â Â Â Â Â this .height = height; Â Â Â Â Â Â Â } Â Â Â Â Â } Â
     function maxStackHeight(ength, width, height) {        let n = length.length;        let boxes = new Array();        let k = 0;        for (let i = 0; i < n; i++) {          boxes[k++] = new Box(length[i], width[i], height[i]);          boxes[k++] = new Box(width[i], height[i], length[i]);          boxes[k++] = new Box(height[i], length[i], width[i]);        } Â
       boxes.sort((b1, b2) => {          // if area of box1 < area of box2          return b1.length * b1.width - b2.length * b2.width;        }); Â
       let dp = new Array(3 * n);        let maxHeight = 0; Â
       for (let i = k - 1; i >= 0; i--) {          dp[i] = boxes[i].height;          for (let j = i + 1; j < k; j++) {            if (              boxes[i].length < boxes[j].length &&              boxes[i].width < boxes[j].width            ) {              dp[i] = Math.max(dp[i], boxes[i].height + dp[j]);            }          } Â
         maxHeight = Math.max(maxHeight, dp[i]);        } Â
       return maxHeight;      } Â
     let length = [4, 1, 4, 10];      let width = [6, 2, 5, 12];      let height = [7, 3, 6, 32]; Â
     console.log(        "The maximum possible height of stack is " +          maxStackHeight(length, width, height)      ); |
C#
using System; using System.Linq; Â
public class BoxStacking { Â Â Â Â public class Box : IComparable<Box> { Â Â Â Â Â Â Â Â public int length; Â Â Â Â Â Â Â Â public int width; Â Â Â Â Â Â Â Â public int height; Â
        public Box( int length, int width, int height) {             this .length = length;             this .width = width;             this .height = height;         } Â
        public int CompareTo(Box b) {             return ( this .length * this .width).CompareTo(b.length * b.width);         }     } Â
    public static int maxStackHeight( int [] length, int [] width, int [] height) {         int n = length.Length;         Box[] boxes = new Box[3 * n]; Â
        int k = 0;         for ( int i = 0; i < n; i++) {             boxes[k++] = new Box(length[i], width[i], height[i]);             boxes[k++] = new Box(width[i], height[i], length[i]);             boxes[k++] = new Box(height[i], length[i], width[i]);         } Â
        Array.Sort(boxes); Â
        int [] dp = new int [3 * n];         int maxHeight = 0; Â
        for ( int i = k - 1; i >= 0; i--) {             dp[i] = boxes[i].height;             for ( int j = i + 1; j < k; j++) {                 if (boxes[i].length < boxes[j].length && boxes[i].width < boxes[j].width) {                     dp[i] = Math.Max(dp[i], boxes[i].height + dp[j]);                 }             } Â
            maxHeight = Math.Max(maxHeight, dp[i]);         } Â
        return maxHeight;     } Â
    public static void Main( string [] args) {         int [] length = { 4, 1, 4, 10 };         int [] width = { 6, 2, 5, 12 };         int [] height = { 7, 3, 6, 32 }; Â
        Console.WriteLine( "The maximum possible height of stack is " + maxStackHeight(length, width, height));     } } |
The maximum possible height of stack is 60
Time Complexity: O(n^2)
Auxiliary Space: O(n)
In the above program, Â for boxes of dimensions of {4, 6, 7}, {1, 2, 3}, {4, 5, 6}, {10, 12, 32} on giving the input as {4, 1, 4, 10} for length, {6, 2, 5, 12} for width and {7, 3, 6, 32} for height. Following rotations are possible for the boxes in decreasing order of base area.Â
32 x 12 x 10 <- 32 x 10 x 12 12 x 10 x 32 <- 7 x 6 x 4 <- 6 x 5 x 4 <- 7 x 4 x 6 6 x 4 x 5 6 x 4 x 7 5 x 4 x 6 <- 3 x 2 x 1 <- 3 x 1 x 2 2 x 1 x 3 <- The maximum possible height of stack is 60
The height 60 is obtained by boxes { {2, 1, 3}, {3, 2, 1}, {5, 4, 6}, {6, 5, 4}, {7, 6, 4}, {12, 10, 32}, {32, 12, 10}}
Please write comments if you find anything incorrect, or if you want to share more information about the topic discussed above.
Â
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!