1. 程式人生 > >POJ-1017(Packets)

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