POJ 1017 Packets

来源:互联网 发布:db2链接数据库 编辑:程序博客网 时间:2024/04/29 11:45
POJ 1017题目大意如下:
有1*1、2*2、3*3、4*4、5*5、6*6这六种型号的包装盒,也指定了相对于这六种型号的产品的分别的数量。由于物流运送费用是和运送商品的数量成正比的(商品运送的时候是包装在包装盒里的),为了节省物流开支,需要确定一种最佳的包装方案,即:使用最少数量的包装盒。
简单的贪心,具体分析如下:
1)都使用6*6的包装盒;
2)如果一个包装盒里包装的是6*6的商品,那么这个包装盒就不能再装其他商品了;
3)如果一个包装盒里包装的是5*5的商品,那么这个包装盒就只能装1*1的商品11个;
4)如果一个包装盒里包装的是4*4的商品,那么这个包装盒就只能装2*2的商品或者1*1的商品了,然而这种情况我们得仔细分析一下:首先知道一个6*6的盒子可以装入4个3*3的商品,向上取整(count3 + 3) / 4 就得到3*3所需的所有盒子数目。对于未装满的6*6的盒子,我们需要对于三种情况分别作分析:
i)如果装入1个3*3的商品,那么可以装入的2*2的盒子数为5,剩余可以装入7个1*1;
ii)如果装入2个3*3的商品,那么可以装入的2*2的盒子数为3,剩余可以装入6个1*1;
iii)如果装入3个3*3的商品,那么可以装入的2*2的盒子数为1,剩余可以装入5个1*1;
假设temp是装入的3*3的数目,count2为2*2的数目,count1为1*1的数目,有下面函数关系:count2 = 7 - 2*tempcount1 = 8 - temp

5)当确定了这些之后,余下的工作就是往3*3~5*5的盒子里填充1*1或者2*2的盒子;
代码如下:
#include <iostream>#include <algorithm>#include <cstdio>#include <cmath>using namespace std;int a[7];int b[] = {0, 5, 3, 1, 0};void solve() {    int sum = a[6] + a[5] + a[4] + (a[3] + 3) / 4;    //先填充5*5的剩余空间    a[1] = max(0, a[1] - 11*a[5]);    if (a[2] > a[4]*5) a[2] -= a[4]*5;    else {        a[1] = max(0, a[1] - 4*(a[4]*5 - a[2]));        a[2] = 0;    }    //找出3*3没有填满的箱子有多少3*3的箱子    int temp = a[3] % 4;    if (temp) {        if (a[2] > 7 - 2*temp) {            a[2] -= 7 - 2*temp;//尽可能填满2*2,根据剩余temp的关系:temp={1,2,3}, count={5,3,1}            a[1] = max(0, a[1] - (8 - temp));//尽可能填满1*1,同样有关系:count={7,6,5}        }        else {            a[1] = max(0, a[1] - 36 + temp*9 + a[2]*4);//尽量放1*1的            a[2] = 0;        }    }    sum += (a[2] + 8) / 9;    if (a[2] % 9) a[1] = max(0, a[1] - 36 + (a[2] % 9)*4);    sum += (a[1] + 35) / 36;    printf("%d\n", sum);}int main(int argc, const char * argv[]) {    // insert code here...    while(true) {        int flag = false;        for (int i = 1; i <= 6; i++) {            scanf("%d", &a[i]);            if (a[i]) flag = true;        }        if (!flag) break;        solve();    }    return 0;}


0 0
原创粉丝点击