題目的主幹意思是: 一個工廠能夠生產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;
}