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;
}



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