java代码,枚举+贪心实现 POJ 1017:装箱问题!!!

1、查看题目

在这里插入图片描述

2、题解思路

        这题的意思是:有一个6x6的盒子,现在,需要将任意个1x1、2x2、3x3、4x4、5x5、6x6的包装装到盒子中去,并且尽可能节省包装用的盒子(控制成本)。
        好,那么我们拿到这题应该如何去思考呢?
        如果你想了半天没想出来,没关系,我们先来看一则小故事:

        :哲学教授上课时拿了一个空的马乃司瓶子,先放进两英寸大的石头;装满后,他又拿了一盒鹅卵石,一边摇晃瓶子,一边将鹅卵石也倒了进去。鹅卵石于是填充了石头间的空隙。最后,老师将一盒细沙倒入了瓶子,终于所有的缝隙全被填满.(ps:如果你想问我马乃司瓶子是什么?那么抱歉!I don't know either)
        好,故事看完了,下面笔笔要开始提问了:请问,你从这则故事中感悟到了什么?。。。。。。那当然是贪心算法啦!每次都先放最大的那个物体,然后再放小的物体,实际上就是通过不断的去构造一个理想的最优子结构,从而达到一个最优解的过程!
        下面我们来分析这道题的一个结构!

        由题意:因为所有包装的height是相同的,所以,它实际上就类似于一个平面的拼图:
在这里插入图片描述
各个尺寸的包装的盒子利用理想情况如下(以下各个尺寸的包装用pN代替,例如p1表示1x1的包装):

  • 6x6的wrap(包装):一个占满一个盒子
  • 5x5的wrap:一个占据一个盒子,余下空间用11个p1填满
  • 4x4的wrap:一个占据一个盒子,余下空间用5个p2填满
  • 3x3的wrap:这个尺寸较为特殊,我们需要分开考虑
    • 1个p3:占据一个盒子,余下空间用5个p2和7个p1填满
    • 2个p3:占据一个盒子,余下空间用3个p2和6个p1填满
    • 3个p3:占据一个盒子,余下空间用1个p2和5个p1填满
    • 4个p3:占满一个盒子。
  • 2x2的wrap:9个占满一个盒子
  • 1x1的wrap:36个占满一个盒子

接下来,我们只需要通过枚举去模拟从大到小去放入包装并计算出结果即可!!!

3、代码实现

ps:如果你和我一样是一个小萌新!那么我建议你先自己思考一遍,实在想不出来再复制我的代码,并且仔细搞懂每一句代码的含义,我会尽量在细节处写上注释,看懂了之后尽量自己写一遍。最后,祝你取得成功!!!

 public static void enum4(int p1,int p2,int p3,int p4,int p5,int p6){
       int sum = 0;
       //make in p6
       if(p6>0) sum+=p6;
       //make in p5
       if(p5>0){  
           sum+=p5;
           //每个p5需要11个p1来填补余下空间,所以需要和当前的p1比较
           //注意,这里不要想当然的把尺寸当做乘法了,虽然余下的空间为11,但你可以试着画一下图
           //当放入一个p5之后,盒子(6x6)的四周只能容下1x1的包装了
           if(p1>=p5*11){ 
               p1-=p5*11;
           }else{ //如果当前p1数小于当前所有p5余下的空间所需的p1数,那么说明能将p1全部放入,p1=0;
               p1=0;
           }
           //下面同理
       }
       //make in p4
       while(p4>0){
           sum++;
           if(p2>=5){
               p2-=5;
           }else{
               int free_Space = (5-p2)*4;
               p2=0;
               if(p1-free_Space>0){
                   p1-=free_Space;
               }else{
                   p1=0;
               }
           }
           p4--;
       }
       //make in p3
       sum += p3/3;
       int p3Sum = p3%4;
       if(p3Sum==1){
           sum++;
           if(p2>=5){
               p2-=5;
               if(p1>=7){
                   p1-=7;
               }else{
                   p1=0;
               }
           }else{
               int free_Space = (5-p2)*4;
               p2=0;
               if(p1>=free_Space){
                   p1-=free_Space;
               }else{
                   p1=0;
               }
           }
       }
       if(p3Sum==2){
            sum++;
            if(p2>=3){
                p2-=3;
                if(p1>=6){
                    p1-=6;
                }else{
                    p1=0;
                }
            }else{
                int free_Space = (3-p2)*4;
                p2=0;
                if(p1>=free_Space){
                    p1-=free_Space;
                }else{
                    p1=0;
                }
            }
        }
       if(p3Sum==3){
            sum++;
            if(p2>=1){
                p2-=1;
                if(p1>=5){
                    p1-=5;
                }else{
                    p1=0;
                }
            }else{
                if(p1>=9){
                    p1-=9;
                }else{
                    p1=0;
                }
            }
        }
       //make in p2
        sum+=p2/9;
        p2%=9;
        if(p2>0){
            sum++;
            if(p1>4*p2){
                p1-=4*p2;
            }else{
                p1=0;
            }
        }
        //make in p1
        while(p1>0){
            if(p1<36){
                sum++;
                break;
            }
            sum++;
            p1-=36;
        }

        System.out.println(sum);
    }

4、结语

以上就是本期的全部内容了,如有其他更好的想法或疑惑的地方,欢迎私信笔笔,同时呢,笔笔最近参加了蓝桥杯的算法比赛,如有意交流的朋友也可以私信笔笔。嗯,最后呢!笔笔想要一个大大滴点赞😳😳,如果这篇文章对你有所帮助的话,还请高抬贵手,给笔笔一个赞!虽然没啥用😂,但是,你的支持是笔笔创作的最大动力ヾ(◍°∇°◍)ノ゙ヾ(◍°∇°◍)ノ゙ヾ(◍°∇°◍)ノ゙ヾ(◍°∇°◍)ノ゙

  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值