装箱问题 ← 模拟法

文章描述了一个工厂如何使用贪心策略为不同尺寸的长方体产品找到最少数量的6x6箱子进行包装的问题。算法分析涉及将问题简化为二维,观察不同产品组合下的剩余空间,并利用模拟和向上取整计算最少箱子数。给出的C++代码实现了这一逻辑,但存在输出限制问题。
摘要由CSDN通过智能技术生成

【题目来源】
http://poj.org/problem?id=1017

【问题描述】
有一个工厂制造的产品形状都是长方体,一共有6种型号,每种型号长方体的长和宽分别是1×1、2×2、3×3、4×4、5×5、6×6,高都是h。这些产品使用统一规格的箱子进行包装,箱子的长、宽和高分别是6、6和h。对于每个订单工厂希望用最少的箱子进行包装。每个订单包括用空格分开的6个整数,分别代表这6种型号的产品数量。输出是包装需要箱子的个数。

 
【输入数据】
输入文件包含若干行,每行表示一个订单。一个订单包含6个用空格分开的整数,分别表示产品1×1至产品6×6的个数。
最后一行6个零,表示输入结束。

【输出数据】
若干行,每行表示当前订单所需的最少箱子数。


【算法分析】
● 在本题中,虽然6种型号的产品及装产品的箱子都被描述为3维的,但由于它们的高度都一样,所以本题可以降为2维问题。即如何将某个订单中1×1、2×2、3×3、4×4、5×5、6×6的正方形放入6×6的正方形中,使得此订单可用最少的6×6正方形容纳。
● 6种规格产品的装箱情况分析,如下表所示:

1个箱子容纳的产品

剩余空间的装载情况

产品

个数

2×2

1×1

解释

6×6

1

0

0

无剩余空间

5×5

1

0

11

11个长度为1的产品

4×4

1

5

0

5个长度为2的产品

3×3

1

5

7

5个长度为2的产品+7个长度为1的产品

3×3

2

3

6

3个长度为2的产品+6个长度为1的产品

3×3

3

1

5

1个长度为2的产品+5个长度为1的产品

3×3

4

0

0

无剩余空间

2×2

9

0

0

无剩余空间

1×1

36

0

0

无剩余空间

通过观察上表可知,当不同规格、不同个数的产品装入6×6的正方形中后,剩余空间只能容纳长度为2的产品及长度为1的产品。特别地,当6×6的正方形中分别装入4,3,2,1个3×3规格的产品后,剩余空间最多可以装0,1,3,5个2×2规格的正方形。
● 本题可以用简单的模拟法来求解。但由于题目要求用最少的6×6正方形完成装箱,故需要用到
贪心策略,即每次装箱时选择某个订单中规格最大的产品先装入,然后选择订单中剩余的规格最大的产品再装入,……,依次类推。
● 计算所需最少箱子数时,注意要
向上取整。若求x/y向上取整的值,有两种方法:一种是ceil(x/y),另一种是(x+y-1)/y

【算法代码】

#include <iostream>
using namespace std;

int main() {
	int n1,n2,n3,n4,n5,n6; //count of 1*1~6*6
	int one,two; //Remaining space for 1*1, 2*2
	int sum; //The number of boxes required

	while(1) {
		cin>>n1>>n2>>n3>>n4>>n5>>n6;
		if(n1+n2+n3+n4+n5+n6==0) break;

		sum=n6+n5+n4+(n3+3)/4; //ceil(n3/4)

		two=n4*5;
		if(n3%4==3) {
			two+=1;
		} else if(n3%4==2) {
			two+=3;
		} else if(n3%4==1) {
			two+=5;
		}
		if(two<n2) { //If have products 2
			sum+=((n2-two)+8)/9; //ceil((n2-two)/9)
		}

		one=36*sum-36*n6-25*n5-16*n4-9*n3-4*n2;
		if(one<n1) { //If have products 1
			sum+=((n1-one)+35)/36; //ceil((n1-one)/36)
		}
		cout<<sum<<endl;
	}

	return 0;
}



/*
in:
0 0 4 0 0 1
7 5 1 0 0 0
0 0 0 0 0 0

out:
2
1
*/

注意:
本例代码,在POJ中提交会提示Output Limit Exceeded。


 

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值