【问题标题】:“cracking the coding interview(fifth edition)”: 9.10 box stacking《破解编码面试(第五版)》:9.10 装箱
【发布时间】:2012-09-24 00:34:53
【问题描述】:

你有一堆 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 &lt;&lt; height &lt;&lt; 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? 

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

【问题讨论】:

    标签: algorithm recursion dynamic-programming


    【解决方案1】:

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

    【讨论】:

    • 这个问题有一个问题:两个相同的盒子,按照问题的严格阅读,可以相互堆叠,这将导致一个循环图。您需要意识到这一点并特别处理它们,或者可能给盒子命名并按字典顺序打破关系,或类似的。
    • @Novak 如果可能的话,你能不能为这个问题写一个递归算法。我正在练习如何编写递归算法。我敢打赌我可以从你的代码中学到很多东西。 :-)。谢谢
    • @Keith Randall 如果可能的话,你能不能为这个问题写一个递归算法。我正在练习如何编写递归算法。我敢打赌我可以从你的代码中学到很多东西。 :-)。谢谢
    • 这只是 Dijkstra 在具有负边权的 DAG 上的算法。您可以在任何地方找到 Dijkstra 的示例。
    • @Novak 第 5 版中的问题是“一个盒子可以堆叠在一个比它大严格的盒子上”,所以没有循环。
    【解决方案2】:

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

    使用索引初始化每个框。

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

    用可以放在上面的盒子运行DFS(相邻的作用)

    维护一个marked[]、count[]和boxTo[]的盒子数组。

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

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

    【讨论】:

      猜你喜欢
      • 2015-12-12
      • 2015-12-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-31
      • 2018-11-21
      • 2013-09-05
      • 1970-01-01
      相关资源
      最近更新 更多