这题是看别人的思路的。。。。
备注:
题目大意:
有1*1,2*2,3*3,4*4,5*5,6*6大小的盒子,要把它们装到6*6的盒子里,它们的高度都是相同的。求用最少的6*6盒子把所有尺寸的盒子都装起来。
分析与总结:
这一题是我在Volume 4. Algorithm Design这个专题中最后才做的一题,主要是因为没有思路。最好还是参考了别人的思路。
6*6的盒子中可以由各种尺寸的盒子来填满。可以有以下这些情况:
1个6*6
1个5*5+11个1*1
1个4*4+5个2*2(有空隙时优先放置2*2,如果没放完2*2的,剩下的就放置1*1)
放置3*3时,组合情况比较复杂。 没有放完3*3时,剩下的空隙也是优先尽可能多地放置2*2
当放置1个3*3时,还可以放置7个1*1和5个2*2
当放置2个3*3时,还可以放置6个1*1和3个2*2
当放置3个3*3时,还可以放置5个1*1和1个2*2
因为一个4*4,5*5,6*6只能放置在一个盒子里,所以有多少个这些,就需要多少个盒子来装。
然后因为3*3的可以和1*1和2*2的组合放置,所以也可以确定装完3*3需要的盒子。
那么在计算时,首先就可以确定放完3*3,4*4,5*5,6*6的盒子个数,假设是t个盒子。
然后这t个盒子中会有空隙,再优先把2*2的放置到t个盒子中的空隙中。如果这些空隙不能放完2*2的,那么就需要再增加盒子知道放完为止。最后在考虑放置1*1。
#include <iostream> #include <cstdio> using namespace std; int a[7]; int three[4][2] = {{0, 0}, {7, 5}, {6, 3}, {5, 1}}; int main() { while (scanf("%d %d %d %d %d %d", &a[1], &a[2], &a[3], &a[4], &a[5], &a[6]) != EOF) { if (!a[1] && !a[2] && !a[3] && !a[4] && !a[5] && !a[6]) break; int num = (a[3] + 3) / 4 + a[4] + a[5] + a[6]; a[1] -= a[5] * 11; int left_2 = three[a[3] % 4][1] + a[4] * 5; if (left_2 >= a[2]) { a[1] -= three[a[3] % 4][0]; a[2] -= left_2; a[1] += a[2] * 4; if (a[1] > 0) num += (a[1] + 35) / 36; } else { a[1] -= three[a[3] % 4][0]; a[2] -= left_2; num += (a[2] + 8) / 9; a[1] -= (9 - a[2] % 9) * 4; if (a[1] > 0) num += (a[1] + 35) / 36; } printf("%d\n", num); } return 0; }