acm(贪心)--装箱问题解题思路和感悟

装箱问题
个工厂制造的产品形状都是长方体,它们的高度都是h,长和宽都相等,一共有六个型号,他们的长宽分别为11, 22, 33, 44, 55, 66 。这些产品通常使用一个 6*6h 的长方体包裹包装然后邮寄给客户。因为邮费很贵,所以工厂要想方设法的减小每个订单运送时的包裹数量 。他们很需要有一个好的程序帮他们解决这个问题从而节省费用。现在这个程序由你来设计。
输入
输入文件由指定订单的几行组成。每行指定一个订单。订单由六个整数描述,这六个整数由一个空格分隔,连续表示从最小尺寸1 x 1到最大尺寸6 x 6的单个尺寸的包的数量。输入文件的末尾由包含六个零的行指示。
输出
输出文件包含输入文件中每行的一行。此行包含可以打包输入文件的相应行的订单的最小数量的宗地。输出文件中没有与输入文件的最后一个“null”行对应的行。
解题思路
1.解决这个问题我一开始想到的是每个订单用一个结构体,来储存每一个订单6种情况的数量。可能是最近刚学了结构体,总是想用。事实证明用结构体十分麻烦,这个问题用不到结构体,定义六个整型就可以来储存6种情况的数量,因为每一个订单都是互不联系的。

2.既然是六种情况,我想的是六种情况单独考虑。6X6的一定是占用一个箱子。在考虑5X5的情况5x5可以与1x1的一起占用一个箱子…以此类推。显然我一开始想的办法是一个错误的方法,运行超时。

3.正确的解题思路:1.六种情况应该统一考虑。4个3x3,4x4,5x5,6x6一定会占用一个箱子。
这时箱子的总数

sum=(c+3)/4+d+e+f;//向上取整,多出的3x3的箱子也要重新占用一个箱子

2.2x2的箱子只能跟4x4,3x3的放在一起

在这里插入图片描述

int n2[4]={0,5,3,1};
b-=(5*d+n2[c%4]);

由此算出2x2剩余的数量。

if(b>0)
                {
                    sum+=ceil(b*1.0/9);
                }

再算出1x1的数量

a-=(36*sum-36*f-25*e-16*d-9*c-4*nb);
            if(a>0)
            {
                sum+=ceil(a*1.0/36);
            }

综合以上:

#include<iostream>
#include<cmath>
using namespace std;
int main()
{
    int a,b,c,d,e,f,g;
    int m,sum=0,nb;
    int n2[4]={0,5,3,1};
    while(cin>>a>>b>>c>>d>>e>>f)
    {
        if(a+b+c+d+e+f==0) break;
        else
        {
            sum=(c+3)/4+d+e+f;
            nb=b;
            b-=(5*d+n2[c%4]);
            if(b>0)
                {
                    sum+=ceil(b*1.0/9);
                }
             a-=(36*sum-36*f-25*e-16*d-9*c-4*nb);
            if(a>0)
            {
                sum+=ceil(a*1.0/36);
            }

        }
        cout<<sum<<endl;
    }
    return 0;
}

感悟:1.通过这个代码学会了许多问题可以分开考虑,若能将分问题结合,会更加简单。
2.在不熟练的情况下,可以综合运用图形,更加直观的看出问题的情况。
3.可以将不同情况,不同答案的问题提前储存在数组之中。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值