
2.2 一往直前!贪心法 其他
有 1 * 1 到 6 * 6 的产品,最少用几个 6 * 6 的箱子装它们。
贪心策略是先装大的,再装小的,看我专门画的图就全明白了。生活常识,桶里先放碎石,再放沙,最后还可以装不少水。 6 * 6 和 5 * 5 以及 4 * 4 肯定独享一个箱子(不可能再放得下同规格的产品)。装了 4 * 4 和 3 * 3 的箱子还可以放 2 * 2 的产品,画个图就知道能放几个:

#include <iostream>
#include <cmath>
using namespace std;
///////////////////////////SubMain//////////////////////////////////
int main(int argc, char *argv[])
{
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
#endif
int n, p1, p2, p3, p4, p5, p6, x , y;
int space[4] = {0, 5, 3, 1}; // 一个箱子放入几个 3 * 3 后留下的缝隙可以放入几个 2 * 2
while(true)
{
cin >> p1 >> p2 >> p3 >> p4 >> p5 >> p6;
if(p1 == 0 && p2 == 0 && p3 == 0 && p4 == 0 && p5 == 0 && p6 == 0)
{
break;
}
// 第一次放“放不下第二个该型号”的型号,需要消耗n个箱子
n = p4 + p5 + p6 + ceil(p3 / 4.0); // 对 3 * 3 的 package 来讲,四个刚好,否则向上取整
// 计算 4 * 4 的型号和 3 * 3 的型号之间的缝隙可以放下多少个 2 * 2 的型号
y = 5 * p4 + space[p3 % 4];
// 2 * 2 的型号填入这些缝隙,如果填不下,再多消耗几个箱子
if(p2 > y)
{
n += ceil((p2 - y) / 9.0); // 多出来的每9个刚好一个箱子
}
// 计算现在空了多少个 1 * 1 的位置
x = 36 * n - 36 * p6 - 25 * p5 - 16 * p4 - 9 * p3 - 4 * p2;
// 1 * 1 的型号填入这些缝隙,如果填不下,再多消耗几个箱子
if(p1>x)
{
n += ceil((p1 - x) / 36.0);
}
cout << n << endl;
}
#ifndef ONLINE_JUDGE
fclose(stdin);
fclose(stdout);
system("out.txt");
#endif
return 0;
}
///////////////////////////End Sub//////////////////////////////////
知识共享署名-非商业性使用-相同方式共享:码农场 » POJ 1017 Packets 题解 《挑战程序设计竞赛(第2版)》练习题答案
码农场