【算法基礎】空瓶換酒

空瓶換酒-python實現

最近學習學習到一種空瓶換酒的算法,其題目描述爲:假設一瓶啤酒2元錢,商家爲了促銷,規定:可以用2個空瓶子換一瓶啤酒,或者用4個蓋子換一瓶啤酒。現在你身上有10元錢,可以買多少瓶啤酒。

1.算法分析

1.1 通常情況

首先假設最後可以用空瓶子換到XX個啤酒,可以用蓋子換到YY個啤酒,同時我們可以用N元錢一開始就買到M個啤酒,就可以得到下面的不等式:
XM+X+Y2<X+1 X \leq \frac{M+X+Y}{2} < X+1
YM+X+Y4<Y+1 Y \leq \frac{M+X+Y}{4} < Y+1
上述兩個公式說明,最後喝到的啤酒數量,肯定不能夠再兌換多一個啤酒。

通過化簡上述公式,可以得到以下公式:
M+Y2<XM+Y   (1) M+Y-2 < X \leq M+Y~~~(1)
M+X43<YM+X3   (2) \frac{M+X-4}{3} < Y \leq \frac{M+X}{3}~~~(2)
化簡上述不等式之後,可以利用不斷遍歷循環,來驗證不同值的情況。

舉個例子:
當有10塊錢,一開始可以買到M=5M=5的啤酒數量,當Y=1Y=1時,通過公式(1)可以得到XX的取值範圍爲X[4,6]X \in [4,6]。然後再把XXYY的幾種情況代入到公式(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瓶啤酒。

發佈了33 篇原創文章 · 獲贊 18 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章