Recursion 叠箱子最高问题 @CareerCup

这类问题要多多画图


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;
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值