1 条题解
-
0
思路与算法
先为每个6、5、4号产品各开一箱。5号余11个单位格,只放1号;4号剩余L形区域可放5个2号,不足的2号空位各补4个1号。3号四件一箱,余r=1、2、3件时再开一箱,分别可补5、3、1件2号,其余面积补1号。剩余2号每9件一箱,末箱再补1号;最后1号每36件一箱。全程只处理数量,不逐件枚举。
正确性说明
整数边长的轴平行正方形装箱可限制到整数坐标:对一个可行布局,每对方块选一个实际成立的左右或上下分离关系;各方向保留这些差分约束,沿对应无环有向关系求最长路压紧,可得不超过原外包尺寸的整数坐标布局。6、5、4号彼此不能同箱,也不能与3号同箱,因此各自开箱不可避免;5号不能与2号同箱,4号剩余20面积至多5件2号且可实现。只含3、2、1号的箱中,固定r件3号时最多可容2号数量F(r)依次为9、5、3、1、0。r=1用棋盘四类奇偶染色可知3号消耗同一类4格、2号每类1格,故≤5;r=2必有一对3号横向或纵向分离,将箱分为两个3宽列,每列最多一个不跨中线的2号,加最多一个跨线2号,故≤3;r=3时必有两个3号组成满宽或满高的半箱,剩下3宽条中只有一个3号,故≤1;r=4面积填满。各上界都有角落放置模板。任意两箱把3号尽量并成4件满箱,剩余3号移到另一箱,查F(0..4)可知总2号容量不会下降;总可放1号面积只取决于已用面积。因此可把3号集中为四件组与一个余箱。已有箱中尽量放2号只会用4格替代至多4个1号;剩余2号9件一箱配1号填空,可达到剩余总面积的向上取整下界。上述逐步选择均不增加箱数,最终最优。
复杂度
每个订单初始化6个计数并进行固定次数算术,O(1)时间、O(1)额外空间;Q个订单总O(Q),输入输出亦O(Q)。
易错点
不是单纯把总面积除36,几何空隙决定能否放下2号。3号余1、2、3时的2号容量5、3、1不能混淆;先扣实际放入的2号,再按剩余面积扣1号,数量最低截到0。六个0是终止符,不输出;数量和答案用64位。
参考代码(C++11)
#include <bits/stdc++.h> using namespace std; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); long long a, b, c, d, e, f; while (cin >> a >> b >> c >> d >> e >> f) { if (!(a || b || c || d || e || f)) break; long long ans = f + e + d + c / 4; a = max(0LL, a - 11 * e); long long used = min(b, 5 * d); b -= used; a = max(0LL, a - 4 * (5 * d - used)); int r = c % 4; if (r) { ++ans; int space[4] = {0, 5, 3, 1}; long long take = min(b, (long long)space[r]); b -= take; a = max(0LL, a - (36 - 9 * r - 4 * take)); } ans += b / 9; if (b % 9) { ++ans; a = max(0LL, a - (36 - 4 * (b % 9))); } ans += (a + 35) / 36; cout << ans << '\n'; } }
- 1