Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 箱子堆放问题_Algorithm_Dynamic Programming - Fatal编程技术网

Algorithm 箱子堆放问题

Algorithm 箱子堆放问题,algorithm,dynamic-programming,Algorithm,Dynamic Programming,我在很多地方发现了这个著名的dp问题,但我不知道如何解决 您将获得一组n种类型的 矩形三维框,其中 盒子具有高度h(i)、宽度w(i)和 深度d(i)(所有实数)。你 要创建一个包含 尽可能高,但你可以 只将一个盒子叠在另一个盒子上 如果 下面的盒子都要大得多 比那些2-D基地的 高一点的盒子。当然,你可以旋转 使任何一边都能起作用的盒子 它的基础。也允许使用 同一类型的多个实例 盒子 这个问题似乎太复杂了,我想不出步骤。由于它是三维的,我得到了三个序列的高度,宽度和深度。但由于可以交换三维空间

我在很多地方发现了这个著名的dp问题,但我不知道如何解决

您将获得一组n种类型的 矩形三维框,其中 盒子具有高度h(i)、宽度w(i)和 深度d(i)(所有实数)。你 要创建一个包含 尽可能高,但你可以 只将一个盒子叠在另一个盒子上 如果 下面的盒子都要大得多 比那些2-D基地的 高一点的盒子。当然,你可以旋转 使任何一边都能起作用的盒子 它的基础。也允许使用 同一类型的多个实例 盒子


这个问题似乎太复杂了,我想不出步骤。由于它是三维的,我得到了三个序列的高度,宽度和深度。但由于可以交换三维空间,这个问题对我来说就变得更复杂了。因此,请有人解释解决问题的步骤时,没有交换,然后如何做时,交换。我对这个问题感到厌倦了。所以请,请有人简单地解释一下解决方案。

我建议您创建一棵树(或某种树结构)并使用深度搜索对其进行解析,从单个垂直“高度”(取决于旋转)值计算最大高度

这(我认为这是基本方法)

细节对细节:

树根应该是地板,任何立方体都可以放在上面。从那里,您只需创建可能的下一个(可以放置在当前框顶部的特定旋转中的框)框的子节点。 递归地对每个框和旋转执行此操作


构建树时,通过它计算从地板到树叶的总塔高。

我认为您可以使用动态规划最长递增子序列算法解决此问题:

计算旋转是很容易的:对于每座塔,你需要检查的是,如果你用它的高度作为基础的长度,用它的宽度作为高度,会发生什么,如果你用自然的方式使用它会发生什么。例如:

=============
=           =
=           =
=           = L
=     H     =
=           =
=           =
=============   
      W
变得像(是的,我知道它看起来一点也不像它应该的样子,只是按照符号):

因此,对于每个块,实际上有3个块表示其可能的旋转。根据这一点调整块数组,然后通过减小基面积进行排序,只需应用DP LIS算法即可获得最大高度

如果最后一个塔必须为i,则调整后的重现期为:D[i]=我们可以获得的最大高度

D[1] = h(1);
D[i] = h(i) + max(D[j] | j < i, we can put block i on top of block j)

Answer is the max element of D.
D[1]=h(1);
D[i]=h(i)+max(D[j]| j

请参阅此处的视频解释:

堆栈可以被视为x、y、z三元组的序列(x、y为2D平面,z为高度),其中x(i)>x(i+1)和y(i)>y(i+1)。目标是最大化从可用三元组集合中选取三元组的z总和-每个三元组是特定方向上的一种盒子类型。很容易看出,强制执行约束x>y并不会减少解决方案空间。所以每个盒子生成3个三元组,w,h,d作为z坐标


如果将三元组视为一个有向无环图,其中当满足x、y约束时,长度为z的边存在于两个三元组之间,那么问题在于找到通过该图的最长路径。

让我们首先尝试在二维中解决此问题:

假设你有X和Y的矩形,问题是类似的(最高的塔,但这次你只需要担心一个基础尺寸)。
因此,首先,您遍历整个集合,通过将每个矩形旋转90度(交换X和Y)来复制每个矩形,除了正方形(其中X(1)=X(2)&&Y(1)=Y(2))。这表示所有可能的变化。
然后按X边从大到小对它们进行排序。如果X值重复,则删除Y值较低的X值

同样的原理也适用于三维场景,只是现在你不只是将集合的大小乘以6(W,H,D的所有可能变体),而是乘以2。通过忽略宽度小于深度的所有变化(因此对于每个i,W(i)>=D(i)),然后忽略高度不是三个维度中最高或最低的变化(因为其他两个变化可以一个在另一个之上,而这个不能合并)。同样,您也会忽略重复(其中W(1)=W(2)和&H(1)=H(2)和&D(1)=D(2))。
然后你应该按宽度排序,只是这次你没有;t丢弃相同宽度的变化(因为一个可能适合另一个可能不适合),然后您可以使用上面@IVlad所述的LIS算法:

D[1] = h(1);
D[i] = h(i) + max(D[j] | j <= i and we can put tower i on tower j) or simply h(i) if no such D[j] exists.
D[1]=h(1);

D[i]=h(i)+max(D[j]|j这个问题的解包括三个步骤

  • 对每个框的尺寸进行排序,以便比较任意两个框减少到比较其相应的尺寸
  • 按字典顺序对框的顺序进行排序,以便对于每个框,左侧的框是可能适合的框
  • 申请
  • 第三步是最昂贵的,它将解决方案的复杂性提升到了O(n^2)

    如果您想阅读该方法的完整解释,请查看每个步骤如何有助于找到答案和完整代码。

    我假设当您旋转它们时,它们必须保持轴对齐?即,您不能旋转30度或类似的角度?旋转意味着可以旋转90度。表示一角硬币不,这不是家庭作业。我正在尝试学习动态编程。这是dp中的一个常见问题。所以我不需要知道。请有人用一些递归关系解释一下。以及为什么你的方法是正确的。这是数量上的指数(阶乘偶数)。他说他特别寻找dp(动态编程)在这里,我得到了高度、宽度和长度的3个序列
    D[1] = h(1);
    D[i] = h(i) + max(D[j] | j <= i and we can put tower i on tower j) or simply h(i) if no such D[j] exists.