描述
一个工厂制造的产品形状都是长方体,它们的高度都是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;
}