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