【算法】阿里巴巴与四十大盗——背包问题
问题描述
有一天,阿里巴巴赶着一头毛驴上山砍柴。砍好柴准备下山时,远处突然出现一股烟尘,弥漫着直向上空飞扬,朝他这儿卷过来,而且越来越近。靠近以后,他才看清原来是一支马队,他们共有四十人,一个个年轻力壮、行动敏捷。一个首领模样的人背负沉重的鞍袋,从丛林中一直来到那个大石头跟前,喃喃地说道:“芝麻,开门吧!”随着那个头目的喊声,大石头前突然出现一道宽阔的门路,于是强盗们鱼贯而入。阿里巴巴待在树上观察他们,直到他们走得无影无踪之后,才从树上下来。他大声喊道:“芝麻,开门吧!”他的喊声刚落,洞门立刻打开了。他小心翼翼地走了进去,一下子惊呆了,洞中堆满了财物,还有多得无法计数的金银珠宝,有的散堆在地上,有的盛在皮袋中。突然看见这么多的金银财富,阿里巴巴深信这肯定是一个强盗们数代经营、掠夺所积累起来的宝窟。为了让乡亲们开开眼界,见识一下这些宝物,他想一种宝物只拿一个,如果太重就用锤子凿开,但毛驴的运载能力是有限的,怎么才能用驴子运走最大价值的财宝分给穷人呢?
阿里巴巴陷入沉思中......
问题分析
【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】贪心算法求解
- 贪心算法之阿里巴巴与四十大盗(背包问题)
- c语言算法—背包问题进阶型(含有两个约束项)
- 贪心算法----背包问题
- 【算法导论实验5】贪心-活动安排问题与背包问题
- 算法0-1背包问题:
- 2.3阿里巴巴与四十大盗 背包问题
- 算法导论--动态规划(0-1背包问题)
- 华为上机试---购物单(算法:背包问题)
- 用贪心算法解背包问题Java实现
- 贪婪算法解决背包问题
- 算法--背包问题
- 贪心算法--背包问题
- 蓝桥杯 算法提高 拿糖果【变形的背包问题】
- PHP贪婪算法解决0-1背包问题实例分析
- 贪心算法;部分背包问题;快速排序O(nlgn);贪心算法O(n);
- 背包问题 算法与原理
- 算法编程(java )#动态规划问题和背包问题
- 第七周算法概论作业—背包问题
- 算法基础课:动态规划之背包问题
- [算法系列之二十九][背包问题]01背包