该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
今天给大家分享一个程序:
600 人站一排,每次随机杀一个奇数位的人,后面的人补上空位,直到最后一个人时,他是几号?
Python 代码:
def fr(a,b = None):
if b is None:
return a
else:
return float(a) / float(b)
# Uncomment the following line to use fractions
# from fractions import Fraction as fr
def cal_p(m, n):
P = [fr(0)] * (m - n + 1)
for M in range(m - n + 1, m + 1):
P2 = [0] * (M+1)
half = (M + 1) // 2
P.append(fr(0))
for i in range(1, M + 1):
if i % 2 == 0:
P2[i] = fr(i // 2, half) * P[i-1] + fr(half - i//2, half) * P[i]
else:
P2[i] = fr(1, half) + fr(i // 2, half) * P[i-1] + fr(half - i//2 - 1, half) * P[i]
P = P2
return P
import matplotlib.pyplot as plt
def plot_q(M,N):
P = cal_p(M,N)
q = [1.0 - p for p in P[1:]]
plt.figure()
plt.plot(q)
plt.show()
if b is None: return a else: return float(a) / float(b)# Uncomment the following line to use fractions# from fractions import Fraction as fr def cal_p(m, n): P = [fr(0)] * (m - n + 1) for M in range(m - n + 1, m + 1): P2 = [0] * (M+1) half = (M + 1) // 2 P.append(fr(0)) for i in range(1, M + 1): if i % 2 == 0: P2[i] = fr(i // 2, half) * P[i-1] + fr(half - i//2, half) * P[i] else: P2[i] = fr(1, half) + fr(i // 2, half) * P[i-1] + fr(half - i//2 - 1, half) * P[i] P = P2 return Pimport matplotlib.pyplot as plt def plot_q(M,N): P = cal_p(M,N) q = [1.0 - p for p in P[1:]] plt.figure() plt.plot(q) plt.show()
如果考虑存活回合数的期望值的话,由于 N 很大的时候存活概率本身就比较小,最后的确应该是 2 的平均存活回合数比较有优势吧。
解释一下当 N 比较大的时候,为什么随着 N 的奇偶性变化,最后一段的概率忽大忽小呢?
因为我们的 M = 600 是个偶数,当杀奇数人的时候,最后一轮排在最后一个位置的人不会被杀,而杀偶数人时,最后这一轮排在最后一个位置的人可能被杀,而就是这一点点差别导致了差异;杀奇数人时,最后一段很容易成为最后一个人,所以存活概率变大了,在杀 599 人的时候,甚至这是唯一的存活可能性;杀偶数人时,反而是成为倒数第二个人比较划算,所以最后一小段反而概率下降了。