盒子堆叠问题

data structuredynamic programmingalgorithms

在这个问题中,给出了一组不同的盒子,不同盒子的长度、宽度和宽度可能不同。我们的任务是找到这些盒子的堆叠,其高度尽可能大。我们可以随意旋转任何盒子。但有一个规则需要遵守。

如果底部盒子的顶面面积大于顶部盒子的下面积,则可以将一个盒子放在另一个盒子上。

输入和输出

输入:
给出了一个盒子列表。每个盒子都用(长度、宽度、高度)表示。
{ (4, 6, 7), (1, 2, 3), (4, 5, 6), (10, 12, 32) }
输出:
箱子堆叠的最大可能高度为:60

算法

maxHeight(boxList, n)

输入 − 不同箱子的列表,箱子数量。

输出 − 通过堆叠箱子找到的最大高度。

Begin
   define rotation array rot of size 3n.
   index := 0

   for all boxes i, in the boxList, do
      rot[index].len := boxList[i].len
      rot[index].hei := maximum of boxList[i].hei and boxList[i].bre
      rot[index].bre := minimum of boxList[i].hei and boxList[i].bre
      index := index + 1

      rot[index].len := boxList[i].bre
      rot[index].hei := maximum of boxList[i].len and boxList[i].hei
      rot[index].bre := minimum of boxList[i].len and boxList[i].hei
      index := index + 1

      rot[index].len := boxList[i].hei
      rot[index].hei := maximum of boxList[i].len and boxList[i].bre
      rot[index].bre := minimum of boxList[i].len and boxList[i].bre
      index := index + 1

      n := 3n
      sort the rot list
      define maxHeightTemp array

      for i := 1 to n-1, do
         for j := 0 to i-1, do
            if rot[i].bre < rot[j].bre AND
               rot[i].hei < rot[j].hei AND
               maxHeightTemp[i] < maxHeightTemp + rot[i].len, then
               maxHeightTemp[i] := maxHeightTemp[j] +
               rot[i].len
         done
      done

      maxHeight := -1
      for i := 0 to n-1, do
         if maxHeight < maxHeightTemp[i], then
            maxHeight := maxHeightTemp[i]
      done
   done
   return maxHeight
End

示例

#include<iostream>
#include<algorithm>
using namespace std;

struct Box {
   int length, bredth, height;
};

int min (int x, int y) {
   return (x < y)? x : y;
}

int max (int x, int y) {
   return (x > y)? x : y;
}

bool compare(Box b1, Box b2) {
   return b1.height > b2.height;    //按高度降序对框进行排序
}

int maxHeight( Box boxList[], int n ) {
   Box rotation[3*n];    //一个框可以旋转为 3 种类型,因此有 3n 次旋转
   int index = 0;

   for (int i = 0; i < n; i++) {
      //存储框的初始位置
      rotation[index].length = boxList[i].length;
      rotation[index].height = max(boxList[i].height, boxList[i].bredth);
      rotation[index].bredth = min(boxList[i].height, boxList[i].bredth);
      index++;

      //第一次旋转后的尺寸
      rotation[index].height = max(boxList[i].length, boxList[i].height);
      rotation[index].bredth = min(boxList[i].length, boxList[i].height);
      index++;        
   
      //第二次旋转后的尺寸
      rotation[index].length = boxList[i].height;
      rotation[index].height = max(boxList[i].length, boxList[i].bredth);
      rotation[index].bredth = min(boxList[i].length, boxList[i].bredth);
      index++;
   }

   n = 3*n;    //将 n 设置为 3n,每个盒子旋转 3 次

   sort(rotation, rotation+n, compare);    //按降序对旋转数组进行排序

   int maxHTemp[n];    //如果第 i 个盒子堆叠,则临时最大高度

   for (int i = 0; i < n; i++ )
      maxHTemp[i] = rotation[i].length;
   
   for (int i = 1; i < n; i++ )    //找到优化的堆叠高度
     对于 (int j = 0; j < i; j++ )
          如果 ( rotation[i].bredth < rotation[j].bredth && rotation[i].height < rotation[j].height
            && maxHTemp[i] < maxHTemp[j] + rotation[i].length) {
              maxHTemp[i] = maxHTemp[j] + rotation[i].length;
           }
   int maxHeight = -1;
   for ( int i = 0; i < n; i++ )    //从所有临时高度中找出最大高度
         
      if ( maxHeight < maxHTemp[i] )
         maxHeight = maxHTemp[i];
         
   return maxHeight;
}

int main() {
   Box arr[] = { {4, 6, 7}, {1, 2, 3}, {4, 5, 6}, {10, 12, 32} };
   int n = 4;
   cout<<"盒子堆叠的最大可能高度为:" << maxHeight (arr, n) << endl;
}

输出

盒子堆叠的最大可能高度为:60

相关文章