离生活最近的数学--换酒定理

97 阅读4分钟

换酒定理构造了一种换酒方法,从而证明了方程的解是有效可靠的

问题引入

餐馆的啤酒售价为5元一瓶。近期节日有促销活动,喝完啤酒后,可以用5个空瓶或10个瓶盖换购一瓶啤酒。此外,消费满100元可以再送一瓶啤酒。现有200元,最多可以喝多少瓶啤酒?

方法1

根据价值守恒

下表为将酒喝完后的状态,每行中 钱+盖+瓶+酒 的总价值为210。

最终喝了58瓶酒,余8个盖和3个瓶。

步骤操作盖数Aₙ瓶数Bₙ累计酒数Cₙ
0送的酒换成钱210000
1210元买酒0424242
2换酒0141442+(4+8)
3换酒07742+(4+8)+(1+2)
4换酒08342+(4+8)+(1+2)+(0+1)=58
5借老板2瓶酒010558+2=60
6还老板2瓶酒00060

Aₙ、Bₙ、Cₙ分别为第n步盖、瓶、酒的情况。

其中:

  • [a/b] 为 a除以b的商
  • a mod b 为 a除以b的余数

A₁=42;B₁=42;C₁=42;Dₙ=ΔCₙ

Dₙ 是每次换酒喝到的酒数

Aₙ = Aₙ₋₁ mod 10 + Dₙ //上步余下的盖+新盖 Bₙ = Bₙ₋₁ mod 5 + Dₙ //上步余下的瓶+新瓶 Dₙ = [Aₙ₋₁/10] + [Bₙ₋₁/5] //上步盖换的酒+上步瓶换的酒

方法2

把钱、盖、瓶、酒全部转换为同样的单位——

把每一个条件转换为1个方程。

约定

  • 1元=1元
  • 1盖=x元
  • 1酒=y元
  • 1瓶=z元

若初始资产为A元,则答案为 A/y。

方程组

A = 42(x+y+z) 10x = x+y+z 5z = x+y+z 5 = x+y+z

联立上面4个方程可得 A/y=60,可以喝60瓶酒。

解方程

百度aistudio

gitpod

安装符号计算库sympy:

pip install sympy

编码:

from sympy import symbols, linsolve

# 定义符号变量
# 1元=1元
# 1盖=x元
# 1酒=y元
# 1瓶=z元
# 若初始资产为A元,则答案为 A/y
x, y, z, A = symbols('x y z A')

# 创建线性方程组
eq1 = 42*(x+y+z) - A
eq2 = x + y + z - 10*x
eq3 = x + y + z - 5*z
eq4 = x + y + z - 5

# 求解线性方程组
result = linsolve([eq1, eq2, eq3, eq4], (x, y, z, A))
# 提取解集中的值
rx,ry,rz,rA = result.args[0]

# 打印解
print(f"1盖={rx}元")
print(f"1酒={ry}元")
print(f"1瓶={rz}元")
print(f"共可以喝 {rA/ry} 瓶酒")
1盖=1/2元
1酒=7/2元
1瓶=1元
共可以喝 60 瓶酒

方法3

与方法2类似,把钱、盖、瓶、酒全部转换为同样的单位——瓶酒盖(U)

  • 1瓶酒盖=1瓶+1酒+1盖=1U
  • 1元=0.2U
  • 1盖=0.1U
  • 1瓶=0.2U
  • 1酒=1U-1盖-1瓶=(1-0.1-0.2)U=0.7U

初始资产=210元=42U

喝的酒数=初始资产/1酒=42U/0.7U=60

换酒定理

酒换干净的充要条件是:初始资产可换整瓶酒b,并且方法2的解s=A/y为整数。

如果没有这个换酒定理,上面的方程组解法是不严谨的,并有可能是错的。

下面的换法是为借老板s-b瓶酒一步到位,不用换来换去了。换酒定理回答了方法2算出的解是否可靠,在现实中是否可操作。

下面构造换法:

约定:

  • P1: 初始资产可换b瓶酒
  • P2: 方法2的解A/y=s
  • P3: 借老板t瓶酒

初始资产+借老板的资产=喝进肚子酒的资产+还老板的资产

b(x+y+z) + t(x+y+z) = sy + s(x+z)

只要t是整数,就存在换法 t=s-b
因为s是喝的酒数, 现实中s必须为整数 所以s和b都为整数才能换干净

根据换酒定理构造的换酒步骤如下:

  1. 先喝下210元买的42瓶酒
  2. 借老板18瓶酒,并喝下,此时已经喝下了60瓶酒
  3. 把手上的60个瓶和60个盖子还给老板,抵消借老板的18瓶酒