/**
* 功能:給你一堆n個箱子,箱子寬wi,高hi,深di。箱子不能翻轉,將箱子堆起來時,下面箱子的寬度、高度和深度必須大於上面的箱子。
* 實現方法:搭出最高的一堆箱子,箱子堆的高度爲每一個箱子高度的總和。java
*/app
兩種方法:this
方法一:遞歸法spa
[java] view plain copy.net
- //遞歸法
- public static ArrayList<Box> createStackR(Box[] boxes,Box bottom){
- int maxHeight=0;
- ArrayList<Box> maxStack=null;
-
- for(int i=0;i<boxes.length;i++){
- if(boxes[i].canBeAbove(bottom)){
- ArrayList<Box> newStack=createStackR(boxes,boxes[i]);
- int newHeight=stackHeight(newStack);
-
- if(newHeight>maxHeight){
- maxHeight=newHeight;
- maxStack=newStack;
- }
- }
- }
-
- if(maxStack==null)
- maxStack=new ArrayList<Box>();
-
- if(bottom!=null)
- maxStack.add(0,bottom);
-
- return maxStack;
- }
-
- public static int stackHeight(ArrayList<Box> stack){
- int height=0;
- for(int i=0;i<stack.size();i++){
- height+=stack.get(i).heigth;
- }
- return height;
- }
方法二:動態規劃code
[java] view plain copyblog
- //動態規劃
- public static ArrayList<Box> createStackDP(Box[] boxes,Box bottem,HashMap<Box,ArrayList<Box>> stackMap){
- if(bottem!=null&&stackMap.containsKey(bottem))
- return stackMap.get(bottem);
-
- int maxHeight=0;
- ArrayList<Box> maxStack=null;
-
- for(int i=0;i<boxes.length;i++){
- if(boxes[i].canBeAbove(bottem)){
- ArrayList<Box> newStack=createStackDP(boxes, boxes[i], stackMap);
- int newHeight=stackHeight(newStack);
-
- if(newHeight>maxHeight){
- maxStack=newStack;
- maxHeight=newHeight;
- }
- }
- }
-
- if(maxStack==null)
- maxStack=new ArrayList<Box>();
- if(bottem!=null)
- maxStack.add(0, bottem);
- stackMap.put(bottem, maxStack);
-
- /**
- * 方法clone()來自Object類,其方法簽名以下:重寫方法時,能夠調整參數,但不得改動返回類型。
- * 所以,若是繼承自Object的類重寫了clone()方法,它的clone()方法仍將返回Object實例。所以必須轉型返回值。
- */
-
- return (ArrayList<Box>) maxStack.clone();//返回副本
- }
-
- lt;pre name="code" class="java"><pre name="code" class="java"> public static int stackHeight(ArrayList<Box> stack){
- int height=0;
- for(int i=0;i<stack.size();i++){
- height+=stack.get(i).heigth;
- }
- return height;
- }
箱子繼承
- class Box{
- int width;
- int heigth;
- int depth;
-
- public Box(int width,int heigth,int depth){
- this.width=width;
- this.heigth=heigth;
- this.depth=depth;
- }
-
- public boolean canBeAbove(Box box){
- if(box.width>this.width&&box.heigth>this.heigth&&box.depth>this.depth)
- return true;
- return false;
- }
- }
或者:遞歸
分析:用遞歸,子問題爲以某一個箱子爲底的高度最高的塔,肯定底後,找到一個能夠放在底上的箱子,再遞歸求解子問題。ip
注意:存在重複子問題,考慮用動態規劃,用表記錄中間結果,以便以後查詢。
[java] view plain copy
- package cci;
-
- import java.util.ArrayList;
-
- class Box{
- int height;
- int width;
- int depth;
- public Box(int height, int width, int depth){
- this.height=height;
- this.width=width;
- this.depth = depth;
- }
- public boolean canBeAbove(Box box){
- if(box==null)
- return true;
- if(height<box.height && width<box.width && depth<box.depth)
- return true;
- return false;
- }
- public void print(){
- System.out.println(height+" "+width+" "+depth);
- }
- }
-
- public class CCI_9_10 {
-
- public static ArrayList<Box> maxBoxTower(Box[] boxes){
- return maxBoxTower(boxes, null);
- }
- private static ArrayList<Box> maxBoxTower(Box[] boxes, Box bottom){
- ArrayList<Box> maxTower = new ArrayList<Box>();
- int maxHeight = 0;
- //嘗試每個箱子
- for(int i=0; i<boxes.length; i++){
- //找到能夠放在bottom上的箱子
- if(boxes[i].canBeAbove(bottom)){
- //以找到的箱子爲底求解子問題(注意,這裏的子問題會被重複求解,提升效率的辦法是動態規劃)
- ArrayList<Box> newTower = maxBoxTower(boxes, boxes[i]);
- //利用子問題的解構造當前問題的解
- int newHeight = calTowerHeight(newTower);
- if(newHeight>maxHeight){
- maxHeight = newHeight;
- maxTower = newTower;//以boxes[i]爲底的最高塔
- }
- }
- }
- if(bottom != null){
- maxTower.add(0, bottom);
- }
- return maxTower;
- }
- private static int calTowerHeight(ArrayList<Box> tower){
- int height=0;
- for(Box box : tower){
- height += box.height;
- }
- return height;
- }
-
-
-
- public static void main(String[] args) {
- // TODO Auto-generated method stub
- Box[] boxes = new Box[3];
- boxes[0] = new Box(1,1,1);
- boxes[1] = new Box(2,2,2);
- boxes[2] = new Box(3,3,3);
- ArrayList<Box> result = maxBoxTower(boxes);
- for(Box item : result){
- item.print();
- }
- }
- }