算法浅谈——怪盗基德的珠宝选择问题与贪心算法

本文始发于个人公众号:TechFlow

1

在开始今天的文章之前,我们先来讲一个故事:

在一个月黑风高的夜晚,怪盗基德潜入了一个著名的珠宝会馆。他面前有三个装着珠宝的柜子,这三个规则分别是A、B和C。每个柜子里装了一个珠宝,这三个珠宝的体积分别是6,5,5,价值分别是10,5, 6。基德每次只能打开一个柜子,他需要将偷出来的珠宝放进随身携带的包里。他的包的体积是10,那么请问,基德应该采取什么策略呢?

图片说明

学过算法的同学会一眼就看出来,这是一个背包问题

我们假装没学过,就按照常理来分析。显然ABC三个珠宝当中A珠宝是最值钱的,由于基德每次只能打开一个柜子,理论上来说应该先拿A。

但是如果拿了A,由于A的体积太大,那么就不能装下B或者C了。所以正确的答案是应该先拿C再拿B,这样能够拿到的价值是11,否则只能装下A一个,价值是10。

我们每次做决定的时候都选择当下回报最多的选项,这种算法叫做贪心法。就好像我们面临三个珠宝去选择最值钱的那个一样,但是当下回报最多并不代表最终的回报最多,所以我们不能只靠眼前的收益来决策。也就是说贪心法是会有反例的。

贪心法有反例这个结论并不难,很容易想明白,难的是我们如何判断当前的问题下,能不能使用贪心算法呢?尤其是我们可能一时半会想不出反例的情况下。

有一个比较取巧的方法叫做均等假设法,这个名字是我取的,没听说过很正常,不用纠结。事实上课本当中谈及贪心算法,也根本不会阐述这个问题,然而这个问题在实际当中又是非常重要的。均等假设法其实很简单,就是假设我们在某次决策的时候,面临两个势均力敌的选项,我们通过判断这两个选项最终的结果是否一致来判断贪心算法是否成立。如果两个均等的选项最终结果一致,那么贪心算法可行,否则不可行。

2

我们还用刚才基德的问题举例:

假设这次基德偷的不再是珠宝,而是非常昂贵的香水,并且假设香水混合之后不会影响它的价值。现在有ABC三瓶香水,每瓶的体积分别是6,5,5价值分别是10,5,5。而基德的瓶子体积是10,显然基德应该先装价值是10的A香水。当基德装完了A香水之后, 瓶子体积还有剩余,这个时候他应该***香水呢还是C香水?

因为B和C香水的价值是一样的,我们试一下就知道,不论我们选B还是C都对最终的结果没有影响。也就是说这两个选项既是均等的,并且它的最终结果也是均等的。那么这个时候,我们就认为贪心算法是可行的。

上述的原理我想大家应该都能看明白,不过可能还会有人有这样一个疑问。我要判断两个选项最终的结果是否一样,既然都能做这样的判断了,那么显然应该早就知道贪心法可不可行了,这怎么还能称为是验证贪心法是否可行的方法呢?

答案也很简单,说起来我们是判断最终的结果是否一致,但实际上,我们只需要判断接下来的若干个中间结果,就可以判断最终结果了。最终结果的说法只是为了表述更加准确,毕竟这不是一个数学上严格的证明方法,而只是我们自己用来推测的方法。

3

我们再来看另一个例子:

柯南的学校最近有很多领导来视察,学校需要安排许多会议,但是学校只有一个会议室,老师们想要知道最多能安排多少会议。老师们为了这件事焦头烂额,只好请来了柯南帮忙。请问柯南应该用什么办法来计算呢?

图片说明

我们假设会议一共有n个,开始的时间是si,结束的时间是ei。我们用贪心算法来解,比较容易想到将所有的会议按照起始时间排序,假设我们按照开始时间排序,依次来安排。我们接下来用刚才的均等假设法来判断这个算法是否可行。

假设存在两个会议的开始时间一样,结束时间不同。那么在当前算法下,这两个会议是均等的。假设这两个会议一个是[1,3],另一个是[1,4]。显然这两个选择的最终结果很有可能不同,因为如果出现一个会议是[3,4]。那么如果选择了第一个会议,就可以安排上,而选择第二个则不能。所以会影响最终结果,因此这种贪心策略不可行。

正解应该是按照结束时间排序,依次安排。我们同样用均等假设法来判断,假设存在两个会议的结束时间一样,并且都能够被安排,它们的时间分别是[2,3]和[1,3]。无论选择它们当中的哪一个,都会在3点结束,对于后面的安排不会产生影响。

你可能会问,如果存在一个[1,2]的会议会怎么样?其实可以证明,不存在这样的会议,因为如果存在,那么根据顺序,应该先安排[1,2]的会议。这样,2点之前开始的会议会被排除在外。那么这两个选项一开始就有一个不成立,自然也就不是均等的了。如果是均等的,那这样的会议就不会存在。

以上就是均等假设法。

4

最后,我们再回到最开始的故事,如果我们是基德,我们真的应该拿B和C吗?

答案是不应该,拿B和C的收益当然是最大的,但是有两个问题。ABC三个珠宝的体积只差了1,我们靠肉眼真的能估算出来,我们拿了A就装不下B或者C了吗?再说,开的柜子越多,被发现的概率也就越大,我们真的可以拿到两个宝石吗?

显然,在现实生活当中贪心法是行不通的,还是应该三思而后行。

本文到这里就结束了,请点个“关注”吧。

图片说明

全部评论

相关推荐

感觉这一周太梦幻了,就像一个梦,很不真实~~~感觉这个暑期,我的运气占了99成,实力只有百分之一4.15上午 腾讯csig 腾讯云部门,面完秒进入复试状态4.16下午 美团优选供应链部门,4.18上午发二面4.17晚上 阿里国际一面,纯拷打,面完我都玉玉了4.18下午 阿里国际二面,是我们leader面的我,很轻松~~4.18晚上 约了hr面4.19上午 hr面,下午两点口头oc4.19晚上 意向书说起来我的暑期好像一次都没挂过~~~~~难道我是天生面试圣体?----------------------------------------------------------------------六个月前,我还是0项目0刷题,当时想的是先把论文发出来再去找实习。结果一次组会,老师打破了我的幻想(不让投B会,只让投刊或者A)我拿头投啊!!!然后就开始物色着找实习,顺便做完了mit的6.s081,但是基本上还是没刷过题目-----------------------------------------------------------------------11月  一次偶然的机会,面进了某个耳机厂的手环部门,大概是做嵌入式的,用的是CPP。12月 莫名其妙拿到了国创的面试机会,0基础四天速成java基础!居然也给我面过了hhhhh,可能是面试没写题吧入职国创后的几个月,一直没活,天天搁那看剧,都快忘了还有暑期实习这回事了~~~~命运的齿轮在2.26开始转动,因为这一天美团开了,我开始慌了,因为那时的我什么都不会。lc,八股,sql全部是0进度。然后就开始了女娲补天,上班刷题,下班继续做之前的开源,顺便学一学八股。3月到现在,lc也刷到快200了,一天最多提交了47次~~~~~~~~~~八股根据别人的面经总结和博客,写了快十万字的笔记~~~~~~~~~~简历上的实习经历和开源,也努力去深挖了,写了几万字的记录~~~~~~所以面试的时候,基本上都能cover了,面试官问到的基础基本都会,不基础的我就把他往我会的地方引。结果好像还不错,基本上每个面试官评价都挺好的emmmmmmmm
投递阿里巴巴等公司10个岗位
点赞 评论 收藏
转发
点赞 评论 收藏
转发
点赞 收藏 评论
分享
牛客网
牛客企业服务