堆栈的盒子-动态规划
Stack of Boxes - 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;
}
我的问题是——这是最优的吗?
不正确。
我用相同的输入尝试了你的代码,除了第三个框的深度,我做了0.5
。
结果如下。它给出了15,而答案应该是10,因为没有其他盒子可以放在第三个盒子的上面。
这段代码实际上是不正确的,因为您假设子问题的最优解可以扩展到包含当前(第n个)框,而实际上并不需要。
示例:{2, 50, 1}, {1, 1, 2}, {1, 3, 3}
(上面的例子没有被这两个排序改变。)你的算法的getP(boxes, 3)
将正确地确定第二个框{1, 1, 2}
是可以先于最终{1, 3, 3}
框的最新框,但是通过请求子问题stackOfBoxes(boxes, 1)
的解决方案,调用代码假设任何框在列表中的第二个框之前(即,无论是第一个框还是第二个框)也可以合法地先于最终{1, 3, 3}
框-但这不是真的。stackOfBoxes(boxes, 1)
最终正确返回2,这只能通过使用第一个盒子来实现——但是外部的stackOfBoxes(boxes, 2)
调用认为它可以在上面添加最后的{1, 3, 3}
盒子,尽管事实上50> 3.
stackOfBoxes(boxes, n)
的返回值的含义。从您在这里编写代码的方式来看,它必须意味着"仅使用索引为<= n的盒子的任何有效堆栈(子序列)可实现的最大高度"。不幸的是,这个问题的表述并没有导致最优子结构。(然而,也有其他表述可以。)
(感谢Nelxiost在我之前对bug的描述中发现了一个bug!)
- 如何解决动态规划问题?
- 动态规划中的旅行推销员问题
- 返回不停止函数,递归函数问题?(编程练习,动态规划,Levenshtein 回溯)
- 寻找最小楼梯成本的动态规划问题的错误答案
- 自上而下的动态规划与递归朴素解决方案.检查运行时执行
- 动态规划 - 原始计算器
- 如何通过动态规划方法解决这个问题?
- C++ 返回具有最小硬币的数组/向量以获得价值动态规划
- 动态规划 - 在数组中查找目标求和方式
- 转换为动态规划算法
- 我的记忆动态规划算法有什么问题?
- 使用动态规划在矩阵中的所有可能路径中具有最小总和的打印路径
- 动态规划:计算集合中存在多少个升序子集
- 错误 C2106:'=':左操作数必须是斐波那契数列中的 l 值,方法是动态规划 C++
- 使用动态规划的值无关背包问题
- 如何知道棒切割算法中杆的所有切割长度?(动态规划)
- 使用一维数组的LCS动态规划
- 动态规划,遍历方法
- 使用动态规划的 TSP
- 堆栈的盒子-动态规划