POJ-1017(Packets)

Packets

POJ链接:http://poj.org/problem?id=1017

//谷歌翻译的,大致意思是对的O(∩_∩)O

描述
工厂生产的产品包装在相同高度h的方形包装中,尺寸为1 * 1,2 * 2,3 * 3,4 * 4,5 * 5,6 * 6。这些产品始终以与产品相同的高度h和尺寸为6 * 6的方形包裹交付给客户。由于费用,工厂和客户的利益是最小化将订购的产品从工厂交付给客户所需的包裹数量。一个好的程序解决了根据订单找到交付给定产品所需的最少数量的包裹的问题,这将节省大量资金。你被要求制作这样的节目。

输入
输入文件由指定订单的几行组成。每行指定一个订单。订单由六个整数描述,这六个整数由一个空格分隔,连续表示从最小尺寸1 * 1到最大尺寸6 * 6的单个尺寸的包的数量。输入文件的末尾由包含六个零的行指示。

产量
输出文件包含输入文件中每行的一行。此行包含可以打包输入文件的相应行的订单的最小数量的宗地。输出文件中没有与输入文件的最后一个“null”行对应的行。

样本输入

0 0 4 0 0 1
7 5 1 0 0 0
0 0 0 0 0 0

样本输出

2
1

 解题思路:

此题意思是尽可能用少的6*6箱子(简称大箱子),装所有的小箱子,所以可以用贪心算法的思想来做,先装大的,再装小的,按照从大到小来装即可,贪心的结果与最优解结果一致(可以用穷举证明,此处略,所以可以简单的分一下类:    

  1. 先装6*6,5*5,4*4的箱子,因为一个箱子只够放一个,所以这几种箱子有多少就要多少个大箱子,5*5箱子还可以放11个1*1,4*4箱子最多可以放5个2*2箱子或者20个1*1箱子
  2. 求出3*3箱子数对4的余数,因为每4个能正好放到一个大箱子里面,故只需统计一下余数即可,则对应还能放2*2箱子个数是(按余数顺序为0,1,2,3,对应数是0,5,3,1),这里对应的是多出的能放2*2箱子的个数(能贪则贪)
  3. 统计一下步骤1和步骤2多出来能放2*2箱子的个数,如果少于给出的2*2箱子数,则需要新开一些箱子来装剩下的2*2箱子(除去之前能利用来放2*2箱子的个数)
  4. 最后统计步骤1,2,3多余的空间,如果该空间比给出1*1箱子数小,那就再开新的大箱子来放剩下的小箱子
  5. 最后说下每步的算式的意义都是尽可能的先装较大的箱子,说白了就是贪( ̄▽ ̄)"

AC代码:

 1 #include<stdio.h>
 2 
 3 int main()
 4 {   //n是总箱子数,i,j分别用来统计多出的箱子数 
 5     int x1, x2, x3, x4, x5, x6, n, i, j; 
 6     int a[] = { 0,5,3,1 };  //放3*3箱子余数为0 1 2 3时可以放的2*2的箱子总数
 7     while (scanf("%d %d %d %d %d %d", &x1, &x2, &x3, &x4, &x5, &x6))//输入每种箱子的个数 
 8     {
 9         n = 0;
10         if (x1 + x2 + x3 + x4 + x5 + x6 == 0)
11         break;
12         n += x6 + x5 + x4 + (x3 + 3) / 4; //整除不影响结果,不整除时可以去整除数+1(即上限)
13         i = x4 * 5 + a[x3 % 4];          //统计多出位置(能放2*2的箱子个数) 
14         if (x2 > i)
15             n += (x2 - i + 8) / 9;//补加还需要新开给2*2的箱子数 
16         j = n * 36 - x6 * 36 - x5 * 25 - x4 * 16 - x3 * 9 - x2 * 4;//统计之前剩余的空间 
17         if (x1 > j)                 //计算还需要新开给1*1的箱子数 
18             n += (x1 - j + 35) / 36;
19         printf("%d\n",n);
20     }
21     return 0;
22 }

如果有更好的算法或者问题,望指出O(∩_∩)O

猜你喜欢

转载自www.cnblogs.com/Diligent-Memory/p/10238163.html
今日推荐