uva--311+贪心

题意:

    货物和箱子是等高的,然后货物的尺寸有1×1,2×2.。。。。6×6六种,箱子的尺寸统一是6*6的。给定6种货物每种的数量,然后求将它们全部装箱所需要的最小箱子数。

思路:

   显然要想箱子数最小,就要尽量把每个箱子都装满,那么我们可以每个箱子都选择先装大的,然后再填充小大(因为装了大的可以填充小的,而装了小的确不一定能再装进大的了)。

   具体的:每个6*6的货物肯定要一个箱子。

                  每个5×5的货物可以和11个1×1的货物装一个箱

                  每个4×4的货物可以和5个2×2的装一个箱

                  3×3货物的情况比较复杂:

                  一个箱子可以装4个3×3的或3个3×3+1个2×2+5个1×1或2个3×3+3个2×2+6个1×1

                 或1个3×3+5个2×2+7个1×1;

                然后就是2×2和1×1的货物依次摆放了。

注意上面如果2×2的货物不够的话就用1×1的补,我们可以假定1×1的货物数目是无限的。(有的解题思路也把2×2的看成无限的,到最后如果小于0再用1×1的补)。

具体实现的时候对2×2货物的数目要注意判定,防止他小于0;


代码如下:


<span style="font-size:18px;">#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;

int main()
{
    int a[9],i,j,k,cnt;
    while(1)
    {
         int flag=0;
         for(i=1;i<=6;i++)
         {
                scanf("%d",&a[i]);
                if(!a[i])
                    flag++;
         }
         if(flag==6)
               break;
        cnt=a[5]+a[6];
        a[1]-=a[5]*11;
        if(a[4]>0)
        {
              cnt+=a[4];
             if(a[2]>=5*a[4])
                  a[2]-=5*a[4];
             else
             {
                if(a[2]>=0)
                {
                      a[1]-=(20*a[4]-a[2]*4);
                      a[2]=0;
                }
             }
        }
        if(a[3]>0)
        {
               cnt+=a[3]/4;
               a[3]=a[3]%4;
               if(a[3])
               {
                       cnt++;
                      if(a[3]==3)
                             k=1;
                      else if(a[3]==2)
                             k=3;
                      else if(a[3]==1)
                             k=5;
                      if(a[2]>=k)
                      {
                            a[2]-=k;
                            j=36-a[3]*9-k*4;
                           a[1]-=j;
                      }
                      else
                      {
                           if(a[2]>=0)
                           {
                                j=36-a[3]*9-a[2]*4;
                               a[1]-=j; a[2]=0;
                            }
                      }
                }
        }
       if(a[2]>0)
       {
             cnt+=a[2]/9;
             a[2]=a[2]%9;
             if(a[2])
             {
                     cnt++;
                      k=36-a[2]*4;
                      a[1]-=k;
             }
       }
        if(a[1]>0)
       {
               cnt+=a[1]/36;
               if(a[1]%36)
                    cnt++;
        }
        printf("%d\n",cnt);
    }
   return 0;
}</span>




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值