可以喝多少瓶啤酒
问题
4个瓶盖,或者2个酒瓶,可以换一瓶啤酒,
现在有10块钱,啤酒2块钱一瓶,问: 共可以喝多少瓶啤酒?
解法一
问题分析
手里有10块钱,既然要喝尽可能多的啤酒,就要买尽可能的多买,所以直接全部买成啤酒,共可买5瓶。现在共有5瓶啤酒,那么可以进行以下的操作(序号越低,优先级越高):
- 如果有酒,则全部喝掉;
- 如果有 >= 4个瓶盖,则换成 n/4 瓶啤酒;
- 如果有 >= 2个酒瓶,则换成 n/2 瓶啤酒;
显然,如果用程序模拟,实现起来很简单。
结果
代码:
# encoding: utf-8 status = (5, 0, 0) # 5瓶酒,0个瓶盖,0个酒瓶 def drink(status): if status[0] != 0: return status[0] + drink((0, status[1] + status[0], status[2] + status[0])) elif status[1] >= 4: return drink((status[1] / 4, status[1] % 4, status[2])) elif status[2] >= 2: return drink((status[2] / 2, status[1], status[2] % 2)) else: return 0 print drink(status)
输出:
15
那么如果初始不是5瓶,一共可以喝多少瓶呢?
初始 | 一共 |
---|---|
0 | 0 |
1 | 1 |
2 | 3 |
3 | 7 |
4 | 11 |
5 | 15 |
6 | 19 |
7 | 23 |
8 | 27 |
9 | 31 |
10 | 35 |
解法二
写一段程序虽然方便快捷,但是还是有很多限制,那么有没有别的方法呢?
问题分析
观察 解法一 的输出数列 0 1 3 7 11 15 19 23 27 31 35,可以发现从 3 开始正是一个等差数列,于是:
结果
\begin{equation*}
f(n) =
\begin{cases}
n & \quad n <= 1\ 4n-5 & \quad n > 1\ \end{cases}
\end{equation*}
解法三
问题分析
- 如果初始有 1 瓶酒:
啤酒 瓶盖 酒瓶 1 0 0 0 1 1 共可喝 1 瓶啤酒,剩余 1 个瓶盖,1 个酒瓶。
即:\(1 \Rightarrow 1 + (0, 1, 1)\)
(注:表示初始 1 瓶,最终可喝 1
瓶,剩余 1 个瓶盖 1 个酒瓶) - 如果初始有 2 瓶酒,只要在 1瓶酒 的基础上加 1瓶酒,然后再化简即可:
啤酒 瓶盖 酒瓶 0 2 2 1 2 0 0 3 1 共可喝 \(1 + 1 + 1 = 3\)
瓶洒,剩余 3 个瓶盖,1 个酒瓶。即:
\(1 \Rightarrow 1 + (0, 1, 1)\) + \(1 \Rightarrow 1 + (0, 1, 1)\) = \(2 \Rightarrow 2 + (0, 2, 2)\) = \(2 \Rightarrow 3 + (0, 3, 1)\) - 如果初始有 3 瓶酒,同理,可以在 2瓶酒 的基础上加 1瓶酒,然后化简:
啤酒 瓶盖 酒瓶 0 4 2 1 0 2 0 1 3 1 1 1 0 2 2 1 2 0 0 3 1 共可喝 \(3 + 1 + 3 = 7\)
瓶酒,剩余 3 个瓶盖,1 个酒瓶。即:
\(2 \Rightarrow 3 + (0, 3, 1)\) + \(1 \Rightarrow 1 + (0, 1, 1)\) = \(3 \Rightarrow 4 + (0, 4, 2)\) = \(3 \Rightarrow 7 + (0, 3, 1)\)
注意,我们发现一个性质:
(0, 3, 1) + (0, 1, 1) = (0, 4, 2) = 3 + (0, 3, 1)
这也意味着,如果我们初始有 2 瓶酒,那么最终可以喝到 3 瓶酒,并剩余 (0, 3, 1)。此后,每拿到 1 瓶额外的酒,就可以再喝这瓶酒本身,加另外可以兑换的 3 瓶酒,即 4
瓶酒,且剩余 (0, 3 , 1)。即对于 n >= 2 的情况,\(f(n) = (n-2) \times 4 + 3 = 4n- 5\)
。因此,可得:
结果
\begin{equation*}
f(n) =
\begin{cases}
n & \quad n <= 1\ 4n-5 & \quad n > 1\ \end{cases}
\end{equation*}
解法四
问题分析
啤酒2元一瓶,4个瓶盖可以换1瓶啤酒,则瓶盖价值0.5元;2个空瓶可以换一瓶啤酒,则空瓶价值1元;进而推出瓶内啤酒的价值是0.5元,所以10元可以喝20瓶。那么具体怎么操作呢?
结果
直接来20瓶,喝完兑换 5+10 瓶,付10元。