【贪心算法】POJ-1017
一、題目
Description
A factory produces products packed in square packets of the same height h and of the sizes 11, 22, 33, 44, 55, 66. These products are always delivered to customers in the square parcels of the same height h as the products have and of the size 6*6. Because of the expenses it is the interest of the factory as well as of the customer to minimize the number of parcels necessary to deliver the ordered products from the factory to the customer. A good program solving the problem of finding the minimal number of parcels necessary to deliver the given products according to an order would save a lot of money. You are asked to make such a program.
Input
The input file consists of several lines specifying orders. Each line specifies one order. Orders are described by six integers separated by one space representing successively the number of packets of individual size from the smallest size 11 to the biggest size 66. The end of the input file is indicated by the line containing six zeros.
Output
The output file contains one line for each line in the input file. This line contains the minimal number of parcels into which the order from the corresponding line of the input file can be packed. There is no line in the output file corresponding to the last ``null'' line of the input file.
Sample Input
0 0 4 0 0 1
7 5 1 0 0 0
0 0 0 0 0 0
Sample Output
2
1
二、思路&心得
- 題目大意為共有1 * 1、2 * 2...6 * 6的產品各a[i]個,包裝袋大小固定為6 * 6,問最少最要多少個包裝袋,可以把每個訂單中所有產品包裝起來。
- 這個題目有點類似硬幣問題,在選擇時從最大的6 * 6的產品開始依次往小進行計算。對于6 * 6、5 * 5、4 * 4的產品,各需要包裝袋a[6]、a[5]、a[4]個,其中放置5 * 5產品的包裝袋可以額外裝11個1 * 1的產品,放置4 * 4產品的可以額外裝5個2 * 2的產品;對于3 * 3的產品比較特殊,對4取模后,根據余數0、1、2、3分四種情況進行判斷,每次選擇時盡可能得裝入更多的2 * 2的產品再裝入1 * 1的產品;對于2 * 2和1 * 1的產品判斷較為簡單,不再多說。
- 在做這題時剛開始有點看不懂題意,便看了下discuss區,發現所有人都說這題非常非常難以及細節很多,導致不敢輕易下手。但是思路想清,WA了一兩次之后,便AC了,好像也沒想象中的那么難。
- 在網上觀摩到大神的極短代碼,算法思想非常精辟,特另附上,以供學習。
三、代碼
我的渣解法:
#include<cstdio>int a[7];int ans;void solve() {ans += (a[4] + a[5] + a[6]);a[1] -= a[5] * 11;a[2] -= a[4] * 5;if (a[2] < 0) {a[1] += a[2] * 4;}ans += (a[3] / 4 + 1);switch (a[3] % 4) {case 0: {ans --;break;}case 1: {if (a[2] > 0) {a[2] -= 5;if (a[2] < 0) {a[1] += a[2] * 4;}a[1] -= 7;} else {a[1] -= 27;}break;} case 2: {if (a[2] > 0) {a[2] -= 3;if (a[2] < 0) {a[1] += a[2] * 4;}a[1] -= 6;} else {a[1] -= 18;}break;}case 3: {if (a[2] > 0) {a[2] -= 1;a[1] -= 5;} else {a[1] -= 9;}break;}}if (a[2] > 0) {ans += a[2] / 9;if (a[2] % 9 > 0) {ans ++;a[1] -= (9 - a[2] % 9) * 4; }}if (a[1] > 0) {ans += (a[1] + 35) /36;}printf("%d\n", ans); }int main () {while (1) {ans = 0;for (int i = 1; i <= 6; i ++) {scanf("%d", &a[i]);}if (!a[1] && !a[2] && !a[3] && !a[4] && !a[5] && !a[6]) break;solve();}return 0; }大神的精辟解法:
#include<stdio.h> int main() {int n,a,b,c,d,e,f,x,y;int u[4]={0,5,3,1};while(1){scanf("%d%d%d%d%d%d",&a,&b,&c,&d,&e,&f);if(a==0&&b==0&&c==0&&d==0&&e==0&&f==0)break;n=d+e+f+(c+3)/4;y=5*d+u[c%4];//在已有n個的情況下,能裝下y個2*2的if(b>y)n+=(b-y+8)/9;//把多的2*2的弄進來x=36*n-36*f-25*e-16*d-9*c-4*b;if(a>x)n+=(a-x+35)/36;//把1*1的弄進來printf("%d\n",n);}return 0; }轉載于:https://www.cnblogs.com/CSLaker/p/7295047.html
總結
以上是生活随笔為你收集整理的【贪心算法】POJ-1017的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: table 样式详解
- 下一篇: 33 Java语言基础控制跳转语句标号