我目前正在练习一些动态编程。我偶然发现了一堆盒子 这些框表示为:
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;
}
答案 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描述中发现了一个错误!)