zoukankan      html  css  js  c++  java
  • [DP] 堆盒子问题

    给一堆盒子,知道每个盒子的三围(长宽高),盒子正面朝你,不能旋转摆放,按照大的放在小的下面的原则堆起来,必须是 strictly larger,同样大小的盒子不行,问怎么样堆到最大的高度?

    思路:动态规划 

    最优解一定是 max( {box_1 be the bottom}, {box_2 be the bottom}, ... , {box_n be the bottom} ),所以我们遍历所有的 box, 把每个box作为底部构建subproblem。

    按说在subproblem {box_1 be the bottom}中,box candidates 中不能再有box_1,因为它已经用作底部了,所以遍历的时候理应跳过 box_1,然而这样会大大增加题目的复杂性。

    幸好这道题有特殊的地方:strictly better, 如果 box_1 已经是底部了,那么即使它在 candidates 中再次出现也不会被选中,就不会产生问题。

    代码:

    package chapter9;
    
    import java.util.ArrayList;
    import java.util.HashMap;
    
    public class P10_book_ {
    
        
        public ArrayList<Box> createStack(Box[] boxes){
            return createStackR(boxes, null, new HashMap<Box, ArrayList<Box>>());
        }
        
        public ArrayList<Box> createStackR(Box[] boxes, Box bottom, 
                HashMap<Box, ArrayList<Box>> stackMap){
            
            if(stackMap.containsKey(bottom))
                return stackMap.get(bottom);
            
            ArrayList<Box> bestStack = new ArrayList<Box>();
            int bestHeight = 0;
            
            for(Box b : boxes){
                if(b.canBeAbove(bottom)){
                    ArrayList<Box> newStack = createStackR(boxes, b, stackMap);
                    int newHeight = stackHeight(newStack);
                    
                    if(newHeight > bestHeight){
                        bestHeight = newHeight;
                        bestStack = newStack;
                    }
                }
            }
            
            // make a copy of bestStack before modify it
            bestStack = (ArrayList<Box>)bestStack.clone();
            
            if(bottom != null)
                bestStack.add(bottom);
            
            stackMap.put(bottom, bestStack);
            return bestStack;
        }
        
        
        
        public int stackHeight(ArrayList<Box> stack){
            
            if(stack == null || stack.isEmpty())
                return 0;
            
            int totalHeight = 0;
            for(Box b : stack){
                totalHeight += b.height;
            }
            return totalHeight;
        }
        
    }
    
    class Box{
        
        int width;
        int height;
        int depth;
        
        public boolean canBeAbove(Box box){
            if(box == null)
                return true;
            
            if(width < box.width && height < box.height && depth < box.depth){
                return true;
            }
            
            return false;
        }
    }
  • 相关阅读:
    POJ 1797 Heavy Transportation (Dijkstra算法变形)
    HDU 2883 kebab (最大流)
    HDU 3338 Kakuro Extension (最大流)
    简单的敏捷工具更受敏捷开发团队青睐
    让敏捷工具在敏捷开发中发挥高效作用
    看板工具和Scrum工具选择之惑!
    敏捷开发如何在创业公司实施
    八个垂手可得的Scrum敏捷开发工具
    那些我们常用的scrum工具、敏捷开发工具
    Scrum/Sprint敏捷开发方法.
  • 原文地址:https://www.cnblogs.com/Antech/p/3788010.html
Copyright © 2011-2022 走看看