“破解编码访谈(第五版)”:9.10框堆叠

时间:2012-10-03 05:36:33

标签: algorithm recursion dynamic-programming

  

你有一堆n个盒子,宽度为wi,高度为hi,深度为   迪。盒子不能旋转,只能堆叠在一个盒子上面   如果堆栈中的每个框大于或等于上面的框,则为另一个框   它的宽度,高度和深度。实现一个构建方法   最高的堆栈可能,堆栈的高度是总和   每个盒子的高度。

我知道有几篇文章要讨论使用动态编程来解决它。由于我想编写递归代码,我编写了以下代码:

const int not_possible = 999999;

class box{
public:
    int width;
    int depth;
    int height;
    box(int h=not_possible, int d=not_possible, int w=not_possible):
        width(w), depth(d), height(h) {}
};


bool check_legal(box lower, box upper){
    return (upper.depth<lower.depth) && 
           (upper.height<lower.height) &&
           (upper.width<lower.width);
}

void highest_stack(const vector<box>& boxes, bool* used, box cur_level, int num_boxes, int height, int& max_height)
{
    if(boxes.empty())
        return;

    bool no_suitable = true;
    for(int i = 0; i < num_boxes; ++i){
        box cur;
        if(!(*(used+i)) && check_legal(cur_level, boxes[i])){
            no_suitable = false;
            cur = boxes[i];
            *(used+i) = true;
            highest_stack(boxes, used, cur, num_boxes, height+cur.height, max_height);
            *(used+i) = false;

                    no_suitable = true;
        }
    }

    if(no_suitable){
        cout << height << endl; //for debug
        if(height > max_height)
            max_height = height;
            return;
    }
}

我用很多例子对它进行了测试。例如:

boxes.push_back(box(4,12,32));
boxes.push_back(box(1,2,3));
boxes.push_back(box(2,5,6));
highest_stack(boxes, used, cur, boxes.size(), 0, max_height);

在函数highest_stack中,有一行cout << height << endl;用于输出。如果我评论no_suitable = true;

  

输出为:1 2 4; 1 2; 1,1 4;

如果我不评论no_suitable = true;

  

输出为:1 2 4; 2 4; 4; 1 2; 2; 1; 1 4; 0

他们两个都可以给出正确的结果,即7。

My question is:
(1) Can anyone help me verify my solution?
(2) Is there any more elegant recursive code for this problem? 
     

我不认为我的代码很优雅。       感谢

2 个答案:

答案 0 :(得分:7)

我会制作一个有向图,其中节点是方框,边缘从一个盒子到一个可以放在它上面的盒子。然后我会使用longest path algorithm来找到解决方案。

答案 1 :(得分:0)

将关系设计为Set数组框。(Set []),即每个位置都有一个框数组。

使用索引初始化每个框。

对于可以放在当前框上方的每个框复选框(方框[i]),将其添加到设置数组中的集合,即set [i] .add(box)

使用可放置在上方的框(相邻角色)

运行DFS

维护标记为[],count []和boxTo []的数组框。

遍历count数组并找到最大值。

使用boxTo []数组遍历到底部框。