POJ 1017 Packet

http://poj.org/problem?id=1017

有1*1 2*2...6*6的物品 要装在 6*6的parcel中 问最少用多少个parcel

一直没有找到贪心的策略

问题应该出现在 总是在想怎么放入parcel中 使得最节省空间

其实这种角度是很麻烦的 情况太多 很难描述清楚

但是其实 放一类型物品 得到的结果是非常具体的

-->>>即从要放的东西的角度出发

放 一个6*6 物品 会占用一个parce

放 一个5*5 物品 会占用一个parce 并且空出11个1*1的空位

放 一个4*4 物品 会占用一个parce 并且空出5个2*2的空位(可以转化为1*1的空位)

放3*3

:放一个 空出 5个2*2的空位 和7个1*1的空位

:放两个 空出 3个2*2的空位 和6个1*1的空位

:放三个 空出 1个2*2的空位 和5个1*1的空位

1*1 和 2*2 的物品作用是用来填补空位的

如果空位被填满 但是物品还未放完  就要再开一个新的parcel

2*2的物品放完后 将所有2*2的空位 变成 1*1的空位 

 1 #include <iostream>
 2 #include <string.h>
 3 #include <stdio.h>
 4 
 5 using namespace std;
 6 //从 六种要装的物品考虑 装每一种物品会空出的空格的情况
 7 int num[8];
 8 int main()
 9 {
10     freopen("in.txt", "r", stdin);
11     int temp = 0;
12     int parcel = 0;
13     int space[6];
14     while (~scanf("%d", &num[0]))
15     {
16         temp = 0;
17         temp |= num[0];
18         memset(space, 0, sizeof(space));
19         parcel = 0;
20         for (int i = 1; i < 6; i++)
21         {
22             scanf("%d", &num[i]);
23             temp |= num[i];
24         }
25         if (!temp) break;
26         parcel = num[5] + num[4] + num[3];
27         space[0] = num[4] * 11;//先解决 6*6,5*5,4*4 的包装盒
28         space[1] = num[3] * 5;
29         //解决3*3的盒子
30         int p3 = 0, remain = 0;
31         remain = num[2] % 4;
32         p3 = remain ? (num[2]/4)+1 : num[2]/4;//如果还有剩余就多开一个盒子
33         parcel += p3;
34         switch(remain)//剩下多少个3*3的物品
35         {
36             case 1: space[1] += 5; space[0] += 7;break;
37             case 2: space[1] += 3; space[0] += 6;break;
38             case 3: space[1] += 1; space[0] += 5;break;
39         }
40         //然后解决 2*2 的盒子
41         remain = min(num[1], space[1]);
42         num[1] -= remain;
43         space[1] -= remain;
44         space[0] += space[1] * 4;
45         if (num[1])
46         {
47             remain = num[1] % 9;
48             if (remain)//如果还有剩余就多开一个盒子
49             {
50                 parcel += num[1] / 9 + 1;
51                 space[0] += 4*(9-remain);
52             }
53             else
54             {
55                 parcel += num[1] / 9;
56             }
57         }
58         //解决1*1
59         num[0] -= min(num[0], space[0]);
60         if (num[0])
61         {
62             remain = num[0] % 36;
63             parcel += remain ? num[0] / 36 + 1 : num[0] / 36;//如果还有剩余就多开一个盒子  后面两个逻辑不严密 没有考虑清楚而出错
64         }
65         printf("%d
", parcel);
66     }
67     return 0;
68 }
原文地址:https://www.cnblogs.com/oscar-cnblogs/p/6360237.html