Introduction
The Box Stacking Problem is a classic Dynamic Programming problem.
We are given three arrays:
height[]width[]length[]
Each index represents one type of box.
Our task is to find the maximum possible height of a stack by placing boxes one above another.
A box can be rotated, meaning any one of its three dimensions can be considered as its height.
A box can be placed on top of another box only when both dimensions of its base are strictly smaller than the base dimensions of the box below it.
Another important condition is that multiple instances of the same box can be used.
Problem Statement
Given:
height[i], width[i], length[i]
for n boxes, find the maximum possible height of the stack.
Conditions
A box can be rotated.
Any dimension can become the height.
Both base dimensions of the upper box must be strictly smaller than the corresponding dimensions of the lower box.
Multiple instances of the same box can be used.
Example
height = [4, 1, 4, 10]
width = [6, 2, 5, 12]
length = [7, 3, 6, 32]
The maximum possible height is:
60
One possible stack has heights:
10 + 32 + 4 + 4 + 6 + 1 + 3 = 60
Understanding Box Rotation
For every box, there are three possible choices for the height.
Suppose a box has:
height = H
width = W
length = L
We can create three orientations.
Rotation 1
Keep H as the height:
Height = H
Base = W × L
Rotation 2
Make W the height:
Height = W
Base = H × L
Rotation 3
Make L the height:
Height = L
Base = H × W
Therefore, n boxes produce:
3 × n
possible orientations.
Why Do We Normalize the Base?
Consider a base:
2 × 5
and another base:
5 × 2
They represent the same physical base.
Therefore, we store the larger dimension first:
max(base1, base2)
and the smaller dimension second:
min(base1, base2)
For example:
2 × 5
becomes:
5 × 2
This makes comparison easier.
Dynamic Programming Approach
After generating all rotations, we need to determine which boxes can be placed on top of which.
Suppose we have two orientations:
Box A:
Base = 10 × 8
Box B:
Base = 7 × 5
Since:
7 < 10
5 < 8
Box B can be placed on top of Box A.
Therefore:
A
↓
B
is a valid stack.
But if:
Box A = 10 × 8
Box B = 9 × 8
then Box B cannot be placed on A because:
9 < 10 → true
8 < 8 → false
The condition must be strictly smaller in both dimensions.
DP State
Let:
dp[i]
represent the maximum height of a stack where orientation i is the bottom box.
Initially:
dp[i] = boxes[i].height
because the box can form a stack by itself.
If another box j can be placed above box i, then:
dp[i] = max(dp[i], boxes[i].height + dp[j])
The condition is:
boxes[j].width < boxes[i].width
AND
boxes[j].length < boxes[i].length
DP Transition
The main transition is:
if boxes[j].w < boxes[i].w
&& boxes[j].l < boxes[i].l
dp[i] = max(dp[i],
boxes[i].h + dp[j])
This means:
If box
jcan be placed on top of boxi, add the best stack height starting fromjto the height ofi.
Finally:
answer = max(dp[i])
gives the maximum possible stack height.
Java Implementation
class Solution {
static class Box {
int h;
int w;
int l;
Box(int h, int w, int l) {
this.h = h;
this.w = w;
this.l = l;
}
}
public int maxHeight(int[] height, int[] width, int[] length) {
int n = height.length;
// Each box has 3 possible orientations
Box[] boxes = new Box[3 * n];
int index = 0;
for (int i = 0; i < n; i++) {
// Rotation 1:
// height = height[i]
boxes[index++] = new Box(
height[i],
Math.max(width[i], length[i]),
Math.min(width[i], length[i])
);
// Rotation 2:
// height = width[i]
boxes[index++] = new Box(
width[i],
Math.max(height[i], length[i]),
Math.min(height[i], length[i])
);
// Rotation 3:
// height = length[i]
boxes[index++] = new Box(
length[i],
Math.max(height[i], width[i]),
Math.min(height[i], width[i])
);
}
int m = boxes.length;
int[] dp = new int[m];
// Initially, every box forms a stack by itself
for (int i = 0; i < m; i++) {
dp[i] = boxes[i].h;
}
int answer = 0;
/*
* Calculate maximum stack height.
*/
for (int i = 0; i < m; i++) {
for (int j = 0; j < m; j++) {
/*
* Box j can be placed on top of box i
* if both base dimensions are smaller.
*/
if (boxes[j].w < boxes[i].w &&
boxes[j].l < boxes[i].l) {
dp[i] = Math.max(
dp[i],
boxes[i].h + dp[j]
);
}
}
answer = Math.max(answer, dp[i]);
}
return answer;
}
}

Join the conversation! Your thoughts help the community grow.