空瓶換酒-python實現
最近學習學習到一種空瓶換酒的算法,其題目描述爲:假設一瓶啤酒2元錢,商家爲了促銷,規定:可以用2個空瓶子換一瓶啤酒,或者用4個蓋子換一瓶啤酒。現在你身上有10元錢,可以買多少瓶啤酒。
1.算法分析
1.1 通常情況
首先假設最後可以用空瓶子換到個啤酒,可以用蓋子換到個啤酒,同時我們可以用N元錢一開始就買到M個啤酒,就可以得到下面的不等式:
上述兩個公式說明,最後喝到的啤酒數量,肯定不能夠再兌換多一個啤酒。
通過化簡上述公式,可以得到以下公式:
化簡上述不等式之後,可以利用不斷遍歷循環,來驗證不同值的情況。
舉個例子:
當有10塊錢,一開始可以買到的啤酒數量,當時,通過公式(1)可以得到的取值範圍爲。然後再把和的幾種情況代入到公式(2)進行驗證。發現上述情況都不符合。
具體的python編程邏輯:
def cal_bar(moneny):
x = 0
y = 0
m = moneny / 2
for y in range(10):
x_min = m + y -2
x_max = m + y
if x_max > x_min > 0:
for i in range(x_min + 1, x_max + 1):
if (m + i - 4) / 3 < y <= (m + i) / 3:
return i, y
return None, None
結果可以喝到15瓶啤酒。
1.2 賒賬情況
上面的情況是不能進行賒賬的,如果能向老闆進行賒賬,則有有種原子操作:
- 目前手上有1個瓶子,向老闆借1個瓶子,然後兌換1個啤酒,喝掉啤酒後,還之前借的酒瓶,這時候的情況是:喝了1個啤酒,得到1個蓋子
- 目前手上有2個蓋子,向老闆借2個蓋子,然後兌換1個啤酒,喝掉之後,這時候生產出1個空瓶和1個蓋子,利用上面的操作再借空瓶,就可以再喝1個啤酒,這時候就可以還掉2個蓋子,實際上:喝了2個啤酒,瓶子和蓋子都沒有剩下
使用這兩種操作,可以得到比不能借的情況下更優的解:
def drink(moneny):
total = 0
wine, bottle, lid = moneny / 2, 0, 0
while True:
if wine != 0:
total += wine
bottle += wine
lid += wine
wine = 0
elif bottle != 0:
total += bottle
lid += bottle
bottle = 0
elif lid >= 2:
total += (lid / 2) * 2
lid %= 2
else:
break
return total
最後可以得到喝了20瓶啤酒。