您的位置:首页 > 其它

【算法】阿里巴巴与四十大盗——背包问题

2022-03-29 17:48 696 查看

问题描述

有一天,阿里巴巴赶着一头毛驴上山砍柴。砍好柴准备下山时,远处突然出现一股烟尘,弥漫着直向上空飞扬,朝他这儿卷过来,而且越来越近。靠近以后,他才看清原来是一支马队,他们共有四十人,一个个年轻力壮、行动敏捷。一个首领模样的人背负沉重的鞍袋,从丛林中一直来到那个大石头跟前,喃喃地说道:“芝麻,开门吧!”随着那个头目的喊声,大石头前突然出现一道宽阔的门路,于是强盗们鱼贯而入。阿里巴巴待在树上观察他们,直到他们走得无影无踪之后,才从树上下来。他大声喊道:“芝麻,开门吧!”他的喊声刚落,洞门立刻打开了。他小心翼翼地走了进去,一下子惊呆了,洞中堆满了财物,还有多得无法计数的金银珠宝,有的散堆在地上,有的盛在皮袋中。突然看见这么多的金银财富,阿里巴巴深信这肯定是一个强盗们数代经营、掠夺所积累起来的宝窟。为了让乡亲们开开眼界,见识一下这些宝物,他想一种宝物只拿一个,如果太重就用锤子凿开,但毛驴的运载能力是有限的,怎么才能用驴子运走最大价值的财宝分给穷人呢?

阿里巴巴陷入沉思中......

问题分析

【1】他想一种宝物只拿一个,如果太重就用锤子凿开,但毛驴的运载能力是有限的,怎么才能用驴子运走最大价值的财宝分给穷人呢? 这话表明,每种宝物只能拿一个,太重了可以用凿子砸开,首先得出结论一定是处于满载状态,并且要价值最大

【2】乍看之下可以有以下2种思路

①每次都挑价值最大的,到装不下为止

②每次都挑重量最小的,到装不下为止

【3】但是这里要注意一个思维误区,题目中并没有说锤子只能用几次,所以可以选择凿开所有的宝物,所以可以引出第三种思路

③每次都挑单位价值最大的宝物,到装不下位置

同学们不要想当然地认为重量和价值是正比关系,铁矿石和钻石就最好的例子,要注意审题,题目中并没有说价值和重量是什么关系,因此价值大的重量不一定大,重量小的价值也不一定小,即便直觉上来说第三种思路肯定最稳妥

算法设计

【1】将n种宝物的重量,价值,性价比封装成一个整体,由高到低排序

【2】根据贪心策略,按照性价比从大到小选取宝物,直到装不下为止

第1次选择宝物2,剩余容量30-2=28,目前装入最大价值为8。

第2次选择宝物10,剩余容量28- -5=23,目前装入最大价值为8+15=23。

第3次选择宝物6,剩余容量23-8=15, 目前装入最大价值为23+20=43。

第4次选择宝物3,剩余容量15-9=6,目前装入最大价值为43+18=61。

第5次选择宝物5,剩余容量6- -5=1,目前装入最大价值为61+8=69。

第6次选择宝物8,发现上次处理完时剩余容量为1,而8号宝物重量为4,无法全部放入,那么可以采用部分装入的形式,装入1个重量单位,因为8号宝物的单位重量价值为1.5, 因此放入价值1x1.5=1.5, 你也可以认为装入了8号宝物的1/4, 目前装入最大价值为69+1.5=70.5,剩余容量为0。

把这些放入的宝物序号组合在一-起,就得到了最优解(2, 10, 6, 3, 5,8),其中最后一个宝物为部分装入(装了8号财宝的1/4),能够装入宝物的最大价值为70.5。

伪代码设计

【1】类定义

class Three{
double w; //每种宝物的重量
double v; // 每种宝物的价值
double p; // 每种宝物的性价比(价值/重量)
}

【2】性价比排序sort()

【3】贪心算法求解

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: