装箱问题(贪心+暴力枚举)

描述

一个工厂制造的产品形状都是长方体,它们的高度都是h,长和宽都相等,一共有六个型号,他们的长宽分别为1*1,2*2,3*3,4*4,5*5,6*6。

这些产品通常使用一个6*6*h的长方体包裹包装然后邮寄给客户。因为邮费很贵,所以工厂要想方设法的减小每个订单运送时的包裹数量。他们很需要有一个好的程序帮他们解决这个问题从而节省费用。现在这个程序由你来设计。

格式

输入格式

输入文件包括几行,每一行代表一个订单。每个订单里的一行包括六个整数,中间用空格隔开,分别为1*1至6*6这六种产品的数量。输入文件将以6个0组成的一行结尾。

输出格式

除了输入的最后一行6个0以外,输入文件里每一行对应着输出文件的一行,每一行输出一个整数代表对应的订单所需的最小包裹数。

样例

输入样例

0 0 4 0 0 1
7 5 1 0 0 0
0 0 0 0 0 0

输出样例

2
1

限制

时间限制: 1000 ms

内存限制: 65536 KB

我看网上其他人关于这个题的贪心解法,这里贴一为博主的贪心解法(下面借用了一些图),基本都是将规律总结出一些公式来AC,但我一开始没想那么多,看着这个题的规模不是很大,noip判分模式能得分总比没有分好,所以直接暴力枚举。

思路:一种费时的笨方法,运用了贪心加枚举,从6*6开始倒序装(贪心),然后枚举每种情况。

1.当放6*6时,箱子刚好满:

 2.当放5*5时,剩下11个1*1:

.3当放4*4时,剩下20个格子,可以放5个2*2,或者20个1*1,再或者2*2与1*1的组合。

4.当放3*3时,每当3*3的数量超过4个时,直接放满一箱,当3*3的数量小于4个时,可组成3*3与2*2与1*1的组合,或者3*3与1*1的组合

5.当放2*2时,先把2*2放满,然后放1*1;

6.当放1*1时,直接放,满了加一个箱。

#include <iostream>
#include <string.h>
#include <algorithm>
using namespace std;

int main()
{
	int a[7], ans=0, area=36;
	bool flag = true;
	while (1) {
		flag = true;
		for (int i=1; i<=6; i++) {
			scanf ("%d", &a[i]);
			if (a[i] != 0) {
				flag = false;
			}
		}
		if (flag == true) {
			break;
		}
		ans=0;
		while(1) {
			flag = true;
			if (a[6]>0) {
				flag = false;
				a[6]--;
				ans++;
				area=36;
			} else if (a[5]>0) {
				a[5]--;
				if (a[1]>=11) {
					a[1] -= 11;
				} else {
					a[1] = 0;
				}
				flag = false;
				ans++;
				area = 36;
			} else if (a[4]>0) {
				a[4]--;
				area -= 16;
				if (a[2]>=5) {
					a[2] -= 5;
				} else {
					a[2] = 0;
					area -= a[2]*4;
						while (a[1]>0 && area>0) {
						area -= 1;
						a[1]--;
					}
				}
				flag = false;
				ans++;
				area=36;
			} else if (a[3]>0) {
				if (a[3]>=4) {
					a[3] -= 4;
				} else {
					area -= (9*a[3]);
					a[3] = 0;
					while (a[2]>0 && area>7) {
						area -= 4;
						a[2]--;
					}
					while (a[1]>0 && area>0) {
						area -= 1;
						a[1]--;
					}
				}
				flag = false;
				ans++;
				area=36;
			} else if (a[2]>0) {
				while (area>0 && a[2]>0) {
					area -= 4;
					a[2]--;
				}
				while (a[1]>0 && area>0) {
					area -= 1;
					a[1]--;
				}
				flag = false;
				ans++;
				area=36;
			} else if (a[1]>0) {
				while (area>0 && a[1]>0) {
					area -= 1;
					a[1]--;
				}
				flag = false;
				ans++;
				area=36;
			}
			if (flag == true)	
				break;
		}
		printf ("%d\n", ans);
	}
	return 0;
}
发布了89 篇原创文章 · 获赞 77 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/wodemaoheise/article/details/104934827