前言
最近遇到的一个问题,感觉可以拓展不少。大概和《算法导论》第五章的在线雇佣问题有些相似。
问题描述
乘坐一个电梯,电梯有10层,你从一楼坐到10楼,每楼有一个大小不一的钻石,你经过每一层楼的时候能看到该层楼的钻石大小,但是你只有一次机会走出电梯去拿。拿完以后,在之后的电梯就不能停留也不能出去拿了。寻找一种策略让你拿到的钻石最大。
我感觉很像苏格拉底苹果林的故事:
几个学生问哲学家苏格拉底:“人生是什么?”
苏格拉底把他们带到一片苹果树林。
要求大家从树林的这头走到那头。
每人挑选一只自己认为最大最好的苹果。
不许走回头路,不许选择两次。
在穿过苹果林的过程中学生们认真细致地挑选自己认为最好的苹果。
等大家来到苹果林的另一端,苏格拉底已经在那里等候他们了。
他问学生:“你们挑到了自己最满意的果子吗?”
大家你看看我我看看你都没有回答。
苏格拉底见状问:“怎么啦,难道你们对自己的选择不满意?”
“老师,让我们再选择一次吧,”一个学生请求说,“我刚走进果林时,就发现了一个很大很好的苹果,但我还想找一个更大更好的。当我走到果林尽头时,才发现第一次看到的那个就是最大最好的。”
另一个接着说:“我和他恰好相反。我走进果林不久,就摘下一个我认为最大最好的果子,可是,后来我又发现了更好的。所以,我有点后悔。”
“老师,让我们再选择一次吧!”其他学生也不约而同地请求。
苏格拉底笑了笑,语重心长地说:“孩子们,这就是人生——人生就是一次无法重复的选择。”
面对无法回头的人生,我们只能做三件事:郑重的选择,争取不留下遗憾;如果遗憾了,就理智的面对它,然后争取改变;假若也不能改变,就勇敢地接受,不要后悔,继续朝前走。
模型
我把这个问题抽象成了有N个数,1,2,3,4……,N在一个数组中。他们的顺序是任意的,什么都有可能,然后你可以从这个数组的第一项开始往后扫描,只能选择一次,如何使选到的钻石最大?
最初想法
我最初的想法是,第一层肯定不选,然后往后走看见第一个比第一层钻石大的就直接拿了。在模型中,大概就是:
假设数组s中有N个数,1~N,然后我从s[0]开始遍历,s[0]直接不选,作为一个参考,然后找到第一个比s[0]大的数就选了。
比如s = [1,2,3],那我会选2
比如s = [1,3,2],那我会选3
比如s = [5,3,2,1,7],那我会选7
这个想法来源于某期《科幻世界》,我已经忘了那个故事里面高大上的概率名字了,反正和什么贝叶斯什么的有关的,然后我也没再搜到这个故事。