100 次抛硬币的最长连正
题
一枚公平硬币连抛 100 次,记 \(L\) 为最长的连续正面段长度。\(E[L]\) 是多少?
一句话
\(E[L] = 5.9918\ldots\),几乎就是 \(\log_2 100 \approx 6.64\) 减去一个常数 \(0.667\)——最长连正随 \(n\) 只以对数速度增长,翻十倍的抛掷次数才换来多约 3.3 的连正。
关键技巧
三件事拼起来就够了。
一、别直接算 \(E[L]\),算尾概率。 对非负整数随机变量,
于是问题变成:100 次抛掷中不出现 \(k\) 连正的概率是多少。
二、\(P(L \le k)\) 有一条两行的 DP。 状态取"当前结尾的连正长度 \(r \in \{0, 1, \ldots, k\}\)",只要没爆表就活着。设 \(u_r^{(t)}\) 是抛完 \(t\) 次、活着且结尾恰有 \(r\) 个正面的概率,则
抛反面就归零,抛正面就右移一格,掉出 \(k\) 之外的概率质量直接丢弃。最后 \(P(L \le k) = \sum_r u_r^{(100)}\)。\(O(nk)\) 就出精确有理数。
把 \(2^n\) 乘回去,这条 DP 就是组合计数里的 \(k\)-bonacci 数列:长度 \(n\)、无 \(k{+}1\) 连续 1 的 01 串个数满足 \(a_n = a_{n-1} + a_{n-2} + \cdots + a_{n-k-1}\)。\(k=1\)(不许两个连 1)时正是斐波那契。
三、估计量级用"起点计数"。 位置 \(i\) 是一段"长度 \(\ge k\) 的连正"的起点(即 \(i-1\) 处是反面或越界,\(i\) 起连着 \(k\) 个正面),概率约 \(\frac{1}{2} \cdot 2^{-k} = 2^{-(k+1)}\)。全序列约有 \(n \cdot 2^{-(k+1)}\) 个这样的起点,且这些事件几乎不重叠,泊松近似给出
令右边等于 \(1/2\):\(k \approx \log_2 n - 2 + \log_2 \frac{1}{\ln 2} \approx \log_2 n - 1.47\),\(n=100\) 时给 5.2;再加上分布右偏拉高的均值,答案就在 6 附近。这是极值理论里的 Gumbel 极限:\(L_n - \log_2 n\) 不收敛到一个点,而是收敛到一个(离散化的)Gumbel 分布,所以方差不随 \(n\) 衰减。
解
DP 跑出来的精确值是一个分母为 \(2^{100}\) 的有理数:
分布本身比均值更有意思:
| \(k\) | \(\le 3\) | 4 | 5 | 6 | 7 | \(\ge 8\) |
|---|---|---|---|---|---|---|
| \(P(L = k)\) | 2.7% | 16.3% | 26.4% | 22.9% | 14.7% | 17.0% |
众数是 5,中位数是 6,均值 \(5.99\)——右边拖着一条长尾(\(P(L \ge 10) = 4.4\%\),\(P(L \ge 15) \approx 0.13\%\))把均值往上拽。
{
"height": 320,
"grid": {"left": 55, "right": 30, "top": 52, "bottom": 40},
"xAxis": {"type": "category", "name": "最长连正 k", "nameLocation": "middle", "nameGap": 26,
"data": ["2","3","4","5","6","7","8","9","10","11","12","13","14","15"]},
"yAxis": {"type": "value", "name": "P(L=k)"},
"series": [{
"type": "bar", "barWidth": "62%",
"data": [
{"value": 0.00026, "itemStyle": {"color": "#bab0ac"}},
{"value": 0.02702, "itemStyle": {"color": "#bab0ac"}},
{"value": 0.16261, "itemStyle": {"color": "#bab0ac"}},
{"value": 0.26402, "itemStyle": {"color": "#4e79a7"}},
{"value": 0.22857, "itemStyle": {"color": "#4e79a7"}},
{"value": 0.14731, "itemStyle": {"color": "#bab0ac"}},
{"value": 0.08265, "itemStyle": {"color": "#bab0ac"}},
{"value": 0.04342, "itemStyle": {"color": "#bab0ac"}},
{"value": 0.02211, "itemStyle": {"color": "#bab0ac"}},
{"value": 0.01109, "itemStyle": {"color": "#bab0ac"}},
{"value": 0.00552, "itemStyle": {"color": "#bab0ac"}},
{"value": 0.00274, "itemStyle": {"color": "#bab0ac"}},
{"value": 0.00136, "itemStyle": {"color": "#bab0ac"}},
{"value": 0.00067, "itemStyle": {"color": "#bab0ac"}}
],
"markLine": {
"symbol": "none",
"label": {"formatter": "E[L] = 5.99", "position": "end", "rotate": 0, "distance": 4,
"color": "#e15759", "fontSize": 12},
"lineStyle": {"color": "#e15759", "width": 2, "type": "dashed"},
"data": [{"xAxis": 3.99}]
}
}]
} 值得记住的一个数:\(P(L \ge 6) = 0.546\)。连抛 100 次,出现 6 连正的机会略高于一半。
延伸
-
渐近公式。Erdős–Rényi / Gordon–Schilling–Waterman 的结果,\(p = \frac12\) 时
\[ E[L_n] \approx \log_2 n - \frac{3}{2} + \frac{\gamma}{\ln 2} = \log_2 n - 0.667\ldots \](\(\gamma \approx 0.5772\) 是欧拉常数。)\(n=100\) 时给 5.977,与精确值只差 0.015;误差大致按 \(1.5/n\) 缩小。公式里还藏着一个周期为 \(\log_2\) 的振荡项,但 2 进制下振幅只有 \(10^{-5}\) 量级,实用中可以忽略。
\(n\) 10 50 100 1000 10000 精确 2.799 5.007 5.992 9.300 12.621 近似 2.655 4.977 5.977 9.299 12.621 -
方差不收缩。渐近方差 \(\dfrac{\pi^2}{6 \ln^2 2} + \dfrac{1}{12} \approx 3.507\)(\(\mathrm{sd} \approx 1.87\)),是 Gumbel 分布方差 \(\pi^2/6\) 换底再加上离散化修正的 \(1/12\)。\(n=100\) 尚未收敛到位,精确方差是 \(3.216\)(\(\mathrm{sd} = 1.79\))。无论抛多少次,最长连正的不确定性都是正负两次左右——它围着 \(\log_2 n\) 抖,永远不会集中。
-
和"等待时间"对照着看。首次出现 \(k\) 连正的期望等待次数是 \(2^{k+1} - 2\)(马尔可夫链或鞅停时都能秒),\(k=6\) 时是 126 次。100 次抛掷比 126 略少,所以 6 连正是"差一点必然发生"——\(P = 0.546\) 正对得上这个直觉。注意别把两者搞混:\(E[\text{等待}] = 126\) 不意味着 100 次里期望连正长度是 6 以下某个精确值,两个期望是不同的量。
-
最长"同面"连段。若问的是最长的连续同面段(正反都算),把序列看成 99 个"与前一次是否相同"的公平指示变量,于是 \(E[R_{100}] = 1 + E[L_{99}] = 6.977\)。经验法则:同面连段比连正长大约 1。
-
它是伪造随机序列的照妖镜。让人凭空编 100 次抛硬币结果,绝大多数人不敢写下 6 连——真实序列却有 55% 的概率出现,写出 7 连的也有 32%。反过来,看到长连段就喊"不随机"往往是错的:\(P(L \ge 8) = 17\%\),一点都不稀奇。这也是体育解说里"手热效应"争议的统计学核心:随机序列本来就长这样。
-
推广到偏心硬币。正面概率 \(p\)、\(q = 1-p\) 时,把上面的 DP 里的 \(\frac12\) 换成 \(p\) / \(q\) 即可,渐近式变成
\[ E[L_n] \approx \log_{1/p}(nq) + \frac{\gamma}{\ln(1/p)} - \frac{1}{2} \]\(p = q = \frac12\) 代入正好回到上式。生存分析、序列比对(BLAST 的 E-value 就建立在同一套连段极值理论上)、金融的最长连涨,用的都是这个骨架。
数值验证
DP 精确解 + 蒙特卡洛交叉验证:
from fractions import Fraction as F
import math, random
def cdf_le(n, k, p=F(1, 2)):
"""P(最长连正 <= k)。状态 = 结尾的连正长度 0..k。"""
q = 1 - p
st = [F(0)] * (k + 1); st[0] = F(1)
for _ in range(n):
new = [F(0)] * (k + 1)
new[0] = sum(st) * q # 抛反面:归零
for r in range(k):
new[r + 1] = st[r] * p # 抛正面:右移;掉出 k 的直接丢弃
st = new
return sum(st)
n = 100
E = sum(1 - cdf_le(n, k) for k in range(n)) # E[L] = sum_k P(L > k)
print(E.denominator == 2 ** 100) # True
print(float(E)) # 5.991780255696744
E2 = sum((2 * k + 1) * (1 - cdf_le(n, k)) for k in range(n))
print(float(E2 - E * E)) # 3.2157436 方差
print(float(1 - cdf_le(n, 5))) # 0.5460936 P(L >= 6)
random.seed(7)
T, tot, hit = 200000, 0, 0
for _ in range(T):
best = cur = 0
for _ in range(n):
if random.getrandbits(1):
cur += 1; best = max(best, cur)
else:
cur = 0
tot += best; hit += best >= 6
print(tot / T, hit / T) # ~5.991 ~0.547
组合视角的同一件事——长度 100、不含 6 连 1 的 01 串共
个,其计数序列 \(1, 2, 4, 8, 16, 32, 63, 125, 248, \ldots\) 从第 7 项起满足六阶递推 \(a_n = a_{n-1} + \cdots + a_{n-6}\)(hexanacci)。