酒瓶算法
题目
两元一瓶啤酒,两个啤酒瓶可换一瓶啤酒,四个啤酒瓶盖可换一瓶啤酒,求10元可以买几瓶啤酒。
好题,好久以前就知道这个题了。择日不如撞日,趁今天在玩Markdown编辑器,就写一篇JS版的算法分析。在去Office的时代里用先进的Markdown才是正道。
解题思路
可以将钱、瓶和盖当成资产来看待,而购买到的啤酒数当成资产的回报ROA
(Return On Assets)。如果可以借贷,那借的酒瓶和盖就是一种流动负债(Current Liabilities)。所以说这是一个涉及经济和计算机算法的好题目,当然这里的借贷是没有成本的借贷。注意没有成本是指不用还利息,而不是不用还。而按兑换关系,酒瓶和钱是可以等量兑换的,因此可以当作同一种资产来看待。
如果允许借瓶子、瓶盖,用完即还。用状态图表示一下,第一列表示钱或者瓶的数量,第二列是盖的数量,第三列是当前已经买到的瓶数,第四、五列是借的瓶、盖数,而第一行表示的是一个初始状态,如给定2元的启动资金:
2 0 0 0 0
1 1 1 0 0
2 2 1 1 1
0 2 2 0 0
0 4 2 0 2
1 0 3 0 1
2 0 3 1 1
0 0 4 0 0
上面这个图就可以当作一个资产负债表(the Balance Sheet)来使用,最后一行就是年报了:}。那么按照这样的处理流程,可以建立一个算法,这个算法需要做的事就是评估输入的资产和借贷状况来取得最大化的资产回报。这个算法还要包含重要的约束,如不可以超货,虽然是无成本借贷,有得借没得还是不道德的。来考虑一下借贷问题,还得起的前提是有足够的资产做抵押,就这个题目来讲,有两种情况是借得通的。只剩1个瓶子时显然可以再借一个,只剩2个瓶盖时再借2个,可以借鸡生蛋换回一瓶一盖,这两种情况下都没有问题。基本流程如下:
- 接收目前资产状态;
- 评估资产性质,将资产最优化;
- 按资产状况最大化资产回报;
- 评估资产状态,决定是否要进入新一轮处理;
代码编写
据此,写出Javascript脚本如下:
var out = function(t){