PKU POJ 1017 Packets 产品包装问题

       题目的主干意思是: 一个工厂能够生产6种不同大小的产品, 分别是1*1, 2*2, 3*3, 4*4, 5*5, 6*6. 而工厂的主要业务是快递这些产品, 但是只有一种6*6规格的包装. 所有为了节省成本, 在向顾客寄出产品时, 希望用最少的包装.

输入(每一行分别为各种产品的数量, 以6个0做为结束):

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

输出(最少需要6*6的包装的数量):

2 
1 


思路如下:

1. 6*6刚好并且只能占用一个包装, 4*4, 5*5得占用一个包装并留下一些空间, 这些空间下面再考虑.

2. 4个3*3可以构成一个6*6, 剩下的3*3得占用一个包装并留下一些空间, 这些空间下面再考虑.

3. 对于5*5剩下的空间, 我们只需要考虑1*1, 因为只能放得下1*1. 对于4*4虽然可以看成1*1或者2*2, 但是显然看成只能容纳2*2比较容易, 而对于3*3就比较麻烦, 

    1个3*3可以容纳 1个2*2和5个1*1, 2个3*3可以容纳 3个2*2和6个1*1, 3个3*3可以容纳 5个2*2和7个1*1(n22=2n-1, n11=n*9-4(2n-1)). 这样对于原来有6种产

     品的情况变成了只有1*1和2*2两种情况.

4. 把上面2*2的空间计算出来 和 提供输入进行比较, 如果2*2的空间还有多的, 那么可以给1*1用, n11= n11 + 剩下的n22*4.如果不够, 下面再考虑.

5. 那现在就简单了, 我们只有1*1了, 和输入的数据进行比较, 如果处理完之后还有剩余或者刚好就不需要再增加包装了. 但如果不够, 下面再考虑.

6. 现在我们可能还有一堆多余的1*1和2*2, 由于2*2能完美构成一个6*6, 而1*1能完美构成一个2*2. 那我们只用考虑((剩下n22 * 4 + 剩下n11) + 35) / 36的值(+35构成向上取整)


解决方法:

由1,2,3可知初始total=n66+n55+n44+(n33+3)/4

计算完了4,5之后

total+=((剩下n22 * 4 + 剩下n11) + 35) / 36


代码:

#include <stdio.h>
#include <stdlib.h>

int i = 0, res[3000];

int main(void) {
        int a[6] = {1, 0, 1, 2, 0, 0}, x = 0, y = 0, z = 0, ly, lz;
        int total = a[5];
        while(1) {
                /*5*5:11个1*1
                 *4*4:5个2*2
                 *3*3:4个3*3 1,5 3,6 5,7*/
                ly = lz = 0;
                total = 0;
                scanf("%d %d %d %d %d %d", &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]);
                if(a[0] == 0&&a[1] == 0&&a[2] == 0&&a[3] == 0&&a[4] == 0&&a[5] == 0) {
                        a[i] = 0;
                        break;
                }

                total += a[5] + a[4] + a[3] + (a[2] + 3) / 4;//4个3*3可以组成一个6*6, 如果有多出, 应该向上取整
                x = (4 - a[2] % 4) % 4;//提供多少个3*3, 范围应该是0-3
                y = a[3] * 5;//提供多少个2*2
                z = a[4] * 11;//提供多少个1*1

                if(x > 0) {
                        y += 2 * x - 1;//3*3的空 能提供多少个2*2
                        z += (x * 9 - (2 * x - 1) * 4);//3*3的空 除了提供2*2剩下的空还可以提供1*1
                }


                if(a[1] > y) {
                        ly += a[1] - y;//如果已有的2*2比 提供的多, 那ly就是多出的部分
                } else {
                        z += (y - a[1]) * 4;//如果2*2处理完了, 那把剩下个2*2空间换成1*1
                }

                if(a[0] > z) {
                        lz += a[0] - z;//如果已有的1*1比 提供的多, 那lz就是多出的部分
                }

                total += ((ly * 4 + lz) + 35) / 36;
                res[i++] = total;
        }

        i = 0;
        while(res[i] != 0) {
                printf("%d\n", res[i++]);
        }
        return EXIT_SUCCESS;
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章