private StackOfBoxes BuildMaxHeightStackRecurse( List <Box> boxes, int index, Dictionary <int, StackOfBoxes> maxStackMap) { if (maxStackMap.ContainsKey(index)) { return(maxStackMap[index]); } StackOfBoxes stackWithBottomIndex = new StackOfBoxes(); stackWithBottomIndex.AddBottom(boxes[index]); StackOfBoxes tallestStackWithBottomIndex = stackWithBottomIndex.Clone(); for (int i = index + 1; i < boxes.Count; i++) { var currentStack = stackWithBottomIndex.Clone(); if (boxes[i] < boxes[index]) { var aboveStack = BuildMaxHeightStackRecurse(boxes, i, maxStackMap); currentStack.Merge(aboveStack); if (tallestStackWithBottomIndex < currentStack) { tallestStackWithBottomIndex = currentStack; } } } maxStackMap[index] = tallestStackWithBottomIndex; return(tallestStackWithBottomIndex); }