8.13 堆箱子

     《程序员面试金典》(第六版)习题:仅为记录一下以加强印象,不为商业用途,如有侵权请联系删除。以下源码和解释参考了书中源码以及解释。
     假设一共有 b o x 1 , b o x 2 , . . . , b o x n box_1, box_2, ..., box_n box1,box2,...,boxnn个箱子。首先找到以箱子 b o x 1 box_1 box1 b o x 2 box_2 box2、…、 b o x n box_n boxn为底的可以堆出的最高箱高,然后求这n个值得最大值即为所求。在求以单个箱子为底的最高箱堆对法的过程中使用了递归思想。

//算法一
int max(int a,int b)
{
	if (a > b)
		return a;
	else
		return b;
}
class Box
{
public:
	int width;
	int height;
	int depth;
	Box(int w, int h, int d)
	{
		width = w;
		height = h;
		depth = d;
	}

	bool canBeUnder(Box b)
	{
		if (width > b.width && height > b.height && depth > b.depth)
		{
			return true;
		}
		return false;
	}

	bool canBeAbove(Box b)
	{
		if (width < b.width && height < b.height && depth < b.depth)
		{
			return true;
		}
		return false;
	}

	string toBoxString()
	{
		return "Box(" + to_string(width) + "," + to_string(height) + "," + to_string(depth) + ")";
	}
};

int createStack(vector<Box> boxes, int bottomIndex)
{
	Box bottom = boxes[bottomIndex];
	int maxHeight = 0;
	for (int i = bottomIndex + 1; i < boxes.size(); i++)
	{
		if (boxes[i].canBeAbove(bottom))
		{
			int height = createStack(boxes, i);
			maxHeight = max(maxHeight, height);
		}
	}
	maxHeight += bottom.height;
	return maxHeight;
}
int createStack(vector<Box> boxes)
{
	Box tempBox(0,0,0);
	for (int i = boxes.size() - 1; i >0 ; i--)
	{
		for (int j = 0; j < i; j++)
		{
			if (boxes[j].height < boxes[j + 1].height)
			{
				tempBox = boxes[j];
				boxes[j] = boxes[j + 1];
				boxes[j+1] = tempBox;
			}
		}
	}

	int maxHeight = 0;
	for (int i = 0; i < boxes.size(); i++)
	{
		int height= createStack(boxes, i);
		maxHeight = max(maxHeight, height);
	}
	return maxHeight;
}

     算法二是对算法一的改进。算法二存储了已经得到的一些结果,避免了一些不必要的重复调用。

//算法二
int createStack(vector<Box> boxes, int bottomIndex,int * stackMap)
{
	if (bottomIndex < boxes.size() && stackMap[bottomIndex]>0)
		return stackMap[bottomIndex];

	Box bottom = boxes[bottomIndex];
	int maxHeight = 0;
	for (int i = bottomIndex + 1; i < boxes.size(); i++)
	{
		if (boxes[i].canBeAbove(bottom))
		{
			int height = createStack(boxes, i, stackMap);
			maxHeight = max(maxHeight, height);
		}
	}
	maxHeight += bottom.height;
	stackMap[bottomIndex]= maxHeight;
	return maxHeight;
}
int createStack(vector<Box> boxes)
{
	Box tempBox(0,0,0);
	for (int i = boxes.size() - 1; i >0 ; i--)
	{
		for (int j = 0; j < i; j++)
		{
			if (boxes[j].height < boxes[j + 1].height)
			{
				tempBox = boxes[j];
				boxes[j] = boxes[j + 1];
				boxes[j+1] = tempBox;
			}
		}
	}

	int maxHeight = 0;
	int* stackMap = new int[boxes.size()];
	for (int i = 0; i < boxes.size(); i++)
	{
		int height= createStack(boxes, i, stackMap);
		maxHeight = max(maxHeight, height);
	}
	return maxHeight;
}

     当对原有的箱子集合按照高度值降序排列后,算法三分为两条递归路径来计算可能的最高堆高度值。一条递归路径以以箱子boexes[offSet]为底,另一条递归路径不以箱子boexes[offSet]为底(堆中排出箱子boexes[offSet])。算法三也使用额外的空间来存储了已经得到的一些结果,避免了一些不必要的重复调用。文章最后有一个简单的测试程序以及对应算法三的递归调用图。

//算法三
int createStack(vector<Box> boxes,Box* bottom, int offSet, vector<int> &stackMap)
{
	if (offSet >= boxes.size())
		return 0;

	Box newBottom = boxes[offSet];
	int heightWithBottom = 0;
	//以下IF语句计算以箱子boexes[offSet]为底的可能堆出的最高堆高度值
	if ((bottom==nullptr)||newBottom.canBeAbove(*bottom))
	{
		if (stackMap[offSet] == 0)
		{
			stackMap[offSet] = createStack(boxes, &newBottom, offSet+1, stackMap);
			stackMap[offSet] += newBottom.height;
		}
		heightWithBottom = stackMap[offSet];
	}
	
	//以下函数调用计算不以箱子boexes[offSet]为底的可能堆出的最高堆高度值(堆中排出箱子boexes[offSet])
    int heightWithoutBottom= createStack(boxes, bottom, offSet + 1, stackMap);
    
	return max(heightWithBottom, heightWithoutBottom);
}
int createStack(vector<Box> boxes)
{
	Box tempBox(0,0,0);
	//对原有的所有的箱子按高度值降序排列
	for (int i = boxes.size() - 1; i >0 ; i--)
	{
		for (int j = 0; j < i; j++)
		{
			if (boxes[j].height < boxes[j + 1].height)
			{
				tempBox = boxes[j];
				boxes[j] = boxes[j + 1];
				boxes[j+1] = tempBox;
			}
		}
	}

	vector<int> stackMap(3,0);
	return createStack(boxes, nullptr, 0, stackMap);
}
//测试程序
int main()
{
	Box one(1, 1, 1);
	Box two(2,2,2);
	Box three(3, 3, 3);
	vector<Box> boxes = { one,two,three };
	cout << createStack(boxes);
}
 
图1.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
´问题描述: 码头仓库是划分为n×m个格子的矩形阵列。有公共边的格子是相邻格子。当前仓库中 有的格子是空闲的;有的格子则已经放了沉重的货物。由于放的货物很重,单凭仓库管 理员的力量是无法移动的。仓库管理员有一项任务,要将一个小箱子推到指定的格子上去。 管理员可以在仓库中移动,但不能跨过已经放了货物的格子。管理员站在与箱子相对的空 闲格子上时,可以做一次推动,把箱子推到另一相邻的空闲格子。推箱时只能向管理员的对 面方向推。由于要推动的箱子很重,仓库管理员想尽量减少推箱子的次数。 ´编程任务: 对于给定的仓库布局,以及仓库管理员在仓库中的位置和箱子的开始位置和目标位置, 设计一个解推箱子问题的分支限界法, 计算出仓库管理员将箱子从开始位置推到目标位置所 需的最少推动次数。 ´数据输入: 由文件input.txt提供输入数据。输入文件第 1 行有 2个正整数 n和 m(1<=n,m<=100) , 表示仓库是n×m个格子的矩形阵列。接下来有 n行,每行有 m个字符,表示格子的状态。 S 表示格子上放了不可移动的沉重货物; w 表示格子空闲; M 表示仓库管理员的初始位置; P 表示箱子的初始位置; K 表示箱子的目标位置。 ´结果输出: 将计算出的最少推动次数输出到文件 output.txt。如果仓库管理员无法将箱子从开始位 置推到目标位置则输出“No solution!” 。 输入文件示例 输出文件示例 input.txt output.txt

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qqssss121dfd

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值