这类问题要多多画图
package Recursion;
import java.util.ArrayList;
import java.util.HashMap;
/**
* You have a stack of n boxes, with widths wi, heights hi and depths di The
* boxes cannot be rotated and can only be stacked on top of one another if each
* box in the stack is strictly larger than the box above it in width, height,
* and depth. Implement a method to build the tallest stack possible, where the
* heigh t of a stack is the sum of the heights of each box.
*
* 你有一叠箱子,每个箱子的宽wi,高hi,深di。箱子不能旋转并且只能把小的放在大的上面,
* 要求宽,高,深都满足。现在要实现一个方法来搭起一个最高的箱子组合。
*/
public class S9_10 {
public static void main(String[] args) {
Box[] boxes = { new Box(1, 7, 4), new Box(2, 6, 9), new Box(4, 9, 6),
new Box(10, 12, 8), new Box(6, 2, 5), new Box(3, 8, 5),
new Box(5, 7, 7), new Box(2, 10, 16), new Box(12, 15, 9) };
ArrayList<Box> stack = createStackDP(boxes, null, new HashMap<Box, ArrayList<Box>>());
for (int i = stack.size() - 1; i >= 0; i--) {
Box b = stack.get(i);
System.out.println(b.toString());
}
}
public static int stackHeight(ArrayList<Box> stack){
if(stack == null){
return 0;
}
int height = 0;
for (Box box : stack) {
height += box.height;
}
return height;
}
public static ArrayList<Box> createStackR(Box[] boxes, Box bottom) {
int maxHeight = 0;
ArrayList<Box> maxStack = new ArrayList<Box>();
for(int i=0; i<boxes.length; i++){
if(boxes[i].canBeAbove(bottom)){
ArrayList<Box> subStack = createStackR(boxes, boxes[i]); // 子问题:把boxes[i]作为bottom
int height = stackHeight(subStack); // 计算子stack的高度
height += (bottom==null ? 0 : bottom.height); // 计算当前stack的总高度
if(height > maxHeight){ // 保存最高高度的组合
maxStack = subStack;
maxHeight = height;
}
}
}
if(bottom != null){
maxStack.add(0, bottom);
}
return maxStack;
}
public static ArrayList<Box> createStackDP(Box[] boxes, Box bottom, HashMap<Box, ArrayList<Box>> stackMap) {
if(bottom!=null && stackMap.containsKey(bottom)){
return stackMap.get(bottom);
}
int maxHeight = 0;
ArrayList<Box> maxStack = new ArrayList<Box>();
for(int i=0; i<boxes.length; i++){
if(boxes[i].canBeAbove(bottom)){
ArrayList<Box> subStack = createStackR(boxes, boxes[i]); // 子问题:把boxes[i]作为bottom
int height = stackHeight(subStack);
height += bottom==null ? 0 : bottom.height;
if(height > maxHeight){
maxStack.addAll(subStack);
maxStack = subStack;
maxHeight = height;
}
}
}
if(bottom != null){
maxStack.add(0, bottom);
stackMap.put(bottom, maxStack);
}
return maxStack;
}
}