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\n", parcel); 66 } 67 return 0; 68 }