堆栈框 - 动态编程

时间:2016-08-19 15:42:05

标签: c++ algorithm dynamic-programming

我目前正在练习一些动态编程。我偶然发现了一堆盒子 这些框表示为:

struct Box{
    double h;
    double w;
    double d;
};

问题在于创建最高堆栈的盒子,其中堆栈中的每个盒子(宽度和深度)都比上面的盒子大。让我们假设在这种情况下不能旋转框。

我将这些框存储在std::vector<Box>中。我首先按宽度然后按深度进行稳定排序,这样每当我选择一个方框时,我只需要向前搜索下一个合适的方框。

这是我的问题 - 这是最佳的吗? 我想每次我选择一个盒子时我需要搜索线性时间(O(n))以便选择下一个可能的盒子。
是否有不同的方式来存储可能在时间复杂度上更好的方框?

当然也欢迎任何其他优化。

我的完整代码:

//Get index of next box that fits or -1 if none
int getP(std::vector<Box>& boxes, int n){
    double n_w = boxes[n].w;
    double n_d = boxes[n].d;
    for (int i=n-1; i >= 0; i--){
        if (n_w > boxes[i].w && n_d > boxes[i].d)
            return i;
    }
    return -1;
}

//Get highest possible stack.
double stackOfBoxes(std::vector<Box>& boxes, int n, Box* bottom){
    if (n == -1)
        return 0;
    if (bottom == NULL || (bottom->d > boxes[n].d && bottom->w > boxes[n].w))
        return max(stackOfBoxes(boxes, n-1, bottom),stackOfBoxes(boxes, getP(boxes,n), &boxes[n])+boxes[n].h);
    else
        return stackOfBoxes(boxes, n-1, bottom);
}


int main(){
    std::vector<Box> boxes = { {3,1,1},{5,2,2},{10,7,7} };
    std::stable_sort(boxes.begin(), boxes.end(), sortByW);
    std::stable_sort(boxes.begin(), boxes.end(), sortByD);

    cout << stackOfBoxes(boxes, 2, NULL) << endl;
}

2 个答案:

答案 0 :(得分:2)

  

这是我的问题 - 这是最佳的吗?

这是不正确的。

我尝试使用相同的输入代码,但我创建的第三个框的深度0.5除外。

Here is the result。它给出了15,答案应该是10,因为没有其他方框可以放在第三个上面。

答案 1 :(得分:1)

代码实际上是不正确的,因为您假设子问题的最佳解决方案可以扩展为包含当前(第n个)框,但不一定。

示例:{2, 50, 1}, {1, 1, 2}, {1, 3, 3}

(上面的例子没有改变2种类型。)你的算法getP(boxes, 3)将正确地确定第二个框{1, 1, 2}是最后一个框,可以在最后{{1}之前但是,通过询问子问题{1, 3, 3}的解决方案,调用代码假设任何框位于列表中的第二个框之前(即,第一个框)方框或第二个)也可以合法地位于最终stackOfBoxes(boxes, 1)框之前 - 但事实并非如此。 {1, 3, 3}最终正确返回2,这只能通过使用第一个框来实现 - 但外部stackOfBoxes(boxes, 1)调用认为它可以在此基础上添加最终stackOfBoxes(boxes, 2)框,尽管50&gt;的事实3。

有助于非常清楚{1, 3, 3} 的返回值是什么意思。从你在这里编写代码的方式来看,它必须意味着“只使用索引为&lt; = n”的方框的任何有效堆栈(子序列)可实现的最大高度。不幸的是,该问题公式导致最佳子结构。 (然而,还有其他配方。)

(感谢Nelxiost在我之前的bug描述中发现了一个错误!)

相关问题