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

时间:2024-10-02 19:13:29

描述

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

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

格式

输入格式

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

输出格式

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

样例

输入样例

  1. 0 0 4 0 0 1
  2. 7 5 1 0 0 0
  3. 0 0 0 0 0 0

输出样例

  1. 2
  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时,直接放,满了加一个箱。

  1. #include <iostream>
  2. #include <string.h>
  3. #include <algorithm>
  4. using namespace std;
  5. int main()
  6. {
  7. int a[7], ans=0, area=36;
  8. bool flag = true;
  9. while (1) {
  10. flag = true;
  11. for (int i=1; i<=6; i++) {
  12. scanf ("%d", &a[i]);
  13. if (a[i] != 0) {
  14. flag = false;
  15. }
  16. }
  17. if (flag == true) {
  18. break;
  19. }
  20. ans=0;
  21. while(1) {
  22. flag = true;
  23. if (a[6]>0) {
  24. flag = false;
  25. a[6]--;
  26. ans++;
  27. area=36;
  28. } else if (a[5]>0) {
  29. a[5]--;
  30. if (a[1]>=11) {
  31. a[1] -= 11;
  32. } else {
  33. a[1] = 0;
  34. }
  35. flag = false;
  36. ans++;
  37. area = 36;
  38. } else if (a[4]>0) {
  39. a[4]--;
  40. area -= 16;
  41. if (a[2]>=5) {
  42. a[2] -= 5;
  43. } else {
  44. a[2] = 0;
  45. area -= a[2]*4;
  46. while (a[1]>0 && area>0) {
  47. area -= 1;
  48. a[1]--;
  49. }
  50. }
  51. flag = false;
  52. ans++;
  53. area=36;
  54. } else if (a[3]>0) {
  55. if (a[3]>=4) {
  56. a[3] -= 4;
  57. } else {
  58. area -= (9*a[3]);
  59. a[3] = 0;
  60. while (a[2]>0 && area>7) {
  61. area -= 4;
  62. a[2]--;
  63. }
  64. while (a[1]>0 && area>0) {
  65. area -= 1;
  66. a[1]--;
  67. }
  68. }
  69. flag = false;
  70. ans++;
  71. area=36;
  72. } else if (a[2]>0) {
  73. while (area>0 && a[2]>0) {
  74. area -= 4;
  75. a[2]--;
  76. }
  77. while (a[1]>0 && area>0) {
  78. area -= 1;
  79. a[1]--;
  80. }
  81. flag = false;
  82. ans++;
  83. area=36;
  84. } else if (a[1]>0) {
  85. while (area>0 && a[1]>0) {
  86. area -= 1;
  87. a[1]--;
  88. }
  89. flag = false;
  90. ans++;
  91. area=36;
  92. }
  93. if (flag == true)
  94. break;
  95. }
  96. printf ("%d\n", ans);
  97. }
  98. return 0;
  99. }