POJ 1017 Packets

本文介绍了一种针对特定尺寸长方体盒子的高效装箱算法,旨在通过合理分配不同大小的盒子来最小化所需的箱子数量,从而降低运输成本。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目 http://poj.org/problem?id=1017

大致题意:
一个工厂制造的产品形状都是长方体盒子,它们的高度都是 h,长和宽都相等,一共有六个型号,分别为1*1, 2*2, 3*3, 4*4, 5*5, 6*6。
这些产品通常使用一个 6*6*h 的长方体箱子包装然后邮寄给客户。因为邮费很贵,所以工厂要想方设法的减小每个订单运送时的箱子数量BoxNum。

解题思路:
由于盒子和箱子的高均为h,因此只需考虑底面积的空间。

6*6的盒子,每个盒子独占一个箱子。
5*5的盒子,每个盒子放入一个箱子,该箱子的剩余空间允许放入的最大尺寸为1*1,且最多放11个。
4*4的盒子,每个盒子放入一个箱子,该箱子的剩余空间允许放入的最大尺寸为2*2。
3*3的盒子,每4个刚好独占一个箱子,不足4个3*3的,剩下空间由2*2和1*1填充。
2*2的盒子和1*1的盒子主要用于填充其他箱子的剩余空间,填充后的多余部分才开辟新箱子装填。

#include <stdio.h>
#include <algorithm>
#include <iostream>
#include <string.h>
using namespace std;

int main()
{
    int s1,s2,s3,s4,s5,s6;    //6中不同尺寸的盒子数目
    while(~scanf("%d %d %d %d %d %d",&s1,&s2,&s3,&s4,&s5,&s6)&&(s1+s2+s3+s4+s5+s6))
    {
        int Boxnum=0;       //我们需要的盒子数目
                            //6*6的单独 装一个
        Boxnum+=s6;


        //              一个 5*5111*1 拼一个盒子
        Boxnum+=s5;
        s1=max(0,s1-11*s5);

        //               一个 4*452*2 或者 4*4 + 201*1

        Boxnum+=s4;
        if(s2>=s4*5)        //如果2*2 的够多 用2*2的填补空出来的位置
        {
            s2=max(0,s2-5*s4);
        }
        else
        {
            s1=max(0,s1-4*(s4*5-s2));   //否则 s1填补剩余的位置(一个2*2的盒子可以用41*1去补位)
            s2=0;                       // s2归0
        }


                        // 3*3的盒子  43*3 
                        // 或者  13*3+52*2+71*1  
                        // 2*s3+3*s2+6*s1    或者  3*s3+s2+5*s1

        Boxnum+= (s3+3)/4;   //3*3的够放在几个盒子里
        s3%=4;               //3*3 的 是否剩余

        if(s3)
        {

            //  根据上面所写,2*2的盒子与3*3的盒子组合时 是 2*2的个数为7-2*(3*3的个数)
            if(s2>=7-2*s3)
            {
                  s2=max(0,s2-(7-2*s3));              //2*2的盒子足够多时
              s1=max(0,s1- (36-9*s3-4*(7-2*s3) ) );  //其余的用1*1去填补空缺
            }
            else
            {
                s1=max(0,s1-(36-s3*9-s2*4));        //2*2的盒子全用上之后剩余的用1*1补
                s2=0;
            }
        }

        //              s2                 2*2的不够用1*1的补位
        Boxnum+=(s2+8)/9;
        s2%=9;
        if(s2)
        {
            s1=max(0,s1-(36-s2*4));
        }

        //   s1
        Boxnum+=(s1+35)/36;

        printf("%d\n",Boxnum);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值