Last Updated: 25 Feb, 2021

Ninja And Stack Of Boxes

Hard
Asked in companies
MicrosoftAdobeNutanix

Problem statement

Ninja has been given ‘N’ rectangular 3-D ‘BOXES’. Each box has dimensions Length ‘L’, Breadth ‘B’ and Height ‘H’. Ninja has to create a stack of boxes as tall as possible. But there is a condition to do so.

You can only place a box on top of another box only 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. You can rotate any box so that any side of the box is used as a base. You can take multiple instances of any box.

Can you help the Ninja to create a stack of boxes as tall as possible?.

Input Format :
The first line of input contains an integer ‘T’ which denotes the number of test cases or queries to be run. Then the test cases follow.

The first line of each test case contains a space-separated integer ‘N’, which represents the number of boxes.

The next ‘N’ lines of each test case contain three space-separated integers ‘L’, ‘B’, and ’H’ that represent the length, breadth, and height of a box.
Output Format :
For each test case, print the maximum height of the stack which can be made using these boxes.

Print the output of each test case in a separate line.

Note :

You do not need to print anything; it has already been taken care of. Just implement the given function.
Constraints :
1 <= ‘T’ <= 100
1 <= ‘N’ <= 5000
1 <= ‘L’, ‘B’, ‘H’ <= 100000 

Time Limit: 1 second

Approaches

01 Approach

As we know we can place a box upon another box if the base area is smaller than the previously selected box. So, first of all, we sort the boxes according to the base area. Then we traverse through all the boxes and assume that the ‘i’th’  box is placed at the bottom. Then we try to place all the remaining boxes on this ‘i’th’ box and calculate the maximum height of the stack.

 

Algorithm:

 

  • We declare a list/vector ‘BOXES’ in which we store every possible rotation of all the boxes.
  • Sort ‘BOXES’ according to the base area.
  • We declare a variable ‘maxHeight’ in which we store the maximum height of the stack.
  • We run a loop for ‘i’ = 0 to ‘BOXES.size()’
    • ‘maxHeight’ = Math.max(‘maxHeight’, ‘ninjaAndStackOfBoxesHelper(‘BOXES’ , ‘i’)’)
  • Finally, return the ‘maxHeight’.

 

ninjaAndStackOfBoxesHelper(‘BOXES’, ‘i’) function is explained below:

 

  • We declare a variable ‘currMaxHeight’ and initialize it with 0.
  • We run a loop for while ‘j’ = ‘i’ + 1 to  ‘BOXES.size()’
    • If ‘BOXES[i].breadth < ‘BOXES[j].breadth’ and ‘BOXES[i].length’ < ‘BOXES[j].length’
      •  ‘currMaxHeight’ = max(‘currMaxHeight’, ninjaAndStackOfBoxesHelper(‘BOXES’, ‘ j’)).
  • ‘currMaxHeight’ += ‘BOXES.height’.
  • Return ‘currMaxHeight’.

02 Approach

We can also optimize our previous approach. There are a lot of overlapping subproblems so we can use an array/vector ‘MEMO’ where ‘MEMO[i]’ denotes the maximum height when the number of boxes is ‘i’. And in which we store our previous calculated result.

 

Algorithm: 

 

  • We declare a list/vector ‘BOXES’ in which we store every possible rotation of all the boxes.
  • Sort ‘BOXES’ according to the base area.
  • We declare a variable ‘maxHeight’ in which we store the maximum height of the stack.
  • We declare a ‘MEMO’ array/vector in which we store our previous calculated result and initialize it with -1.
  • We run a loop for ‘i’ = 0 to ‘BOXES.size()’
    • ‘maxHeight’ = Math.max(‘maxHeight’, ‘ninjaAndStackOfBoxesHelper(‘BOXES’ , ‘i’, ‘MEMO’)’)
  • Finally, return the ‘maxHeight’.

 

ninjaAndStackOfBoxesHelper(‘BOXES’, ‘i’, ‘MEMO’ ) function is explained below:

 

  • If ‘i’ < ‘BOXES.size()’ and  ‘MEMO[i] != -1’
    • Return ‘MEMO[i]’
  • We declare a variable ‘currMaxHeight’ and initialize it with 0.
  • We run a loop while ‘j’ = ‘i’ + 1 to  ‘BOXES.size()’
    • If ‘BOXES[i].breadth < ‘BOXES[j].breadth’ and ‘BOXES[i].length’ < ‘BOXES[j].length’
      •  ‘currMaxHeight’ = max(‘currMaxHeight’, ninjaAndStackOfBoxesHelper(‘BOXES’, ‘ j’)).
  • ‘currMaxHeight’ += ‘BOXES.height’.
  • ‘MEMO[i]’ = ‘currMaxHeight’
  • Return ‘currMaxHeight’.

03 Approach

As we know we can place a box upon another box if the base area is smaller than the previously selected box. So, first of all, we sort the boxes according to the base area. Then we declare an array/vector ‘MAXI_HEIGHT’ in which we store the maximum height of the stack of boxes when the ‘i’ box is at the top of the stack of boxes. To find this we use the longest Increasing subsequence approach.

 

Algorithm: 

 

  • We declare a list/vector ‘BOXES’ in which we store every possible rotation of all the boxes.
  • Sort ‘BOXES’ according to the base area.
  • We declare a list/vector ‘MAXI_HEIGHT’ in which we store the maximum height of the stack of boxes when the ‘i’ box is at the top of the stack of boxes.
  • We run a loop for ‘i’ = 0  to ‘BOXES.size()’:
    • ‘MAXI_HEIGHT[i] = ‘BOXES.get(i).h’
  • We run a loop for ‘i’ = 0 to ‘BOXES.size()’:
    • We run a loop for ‘j’ = 0 to ‘i’:
      • Then we check if we can place the ‘i’ box on top of the ‘j’ box.
      • If ‘BOXES[i].breadth < ‘BOXES[j].breadth’ and ‘BOXES[i].length’ < ‘BOXES[j].length’
        •  ‘MAXI_HEIGHT[i]’ = max(‘MAXI_HEIGHT[i]’,  ‘MAXI_HEIGHT[j]’ + BOXES[i].height)
  • Finally, we traverse on the ‘MAXI_HEIGHT’ and find the maximum height and then return the maximum height.