概率DP与期望DP:随机问题的完整推导

前言

概率DP是动态规划在概率问题上的应用。投骰子几次能到达终点? 看似随机的问题,背后有严密的数学期望推导。很多人只记住公式,却不知道期望的线性性、为什么逆推而不是正推。

我并没有能力让你成为概率论专家,我只是想让你彻底理解概率DP的状态定义、期望的数学性质、以及为什么有些问题要逆推。每个公式都会详细证明,作为算法系列40篇的完美收官。

摘要

从"骰子期望步数"问题出发,剖析概率DP的核心思想与数学推导。通过期望的定义与性质、正推与逆推的选择依据、以及全期望公式的应用,揭秘如何用DP求解随机问题。配合详细数学证明,给出概率DP的透彻理解。


一、什么是期望

周一早上,哈吉米南北绿豆:"数学期望是什么?"

南北绿豆:"期望就是随机变量的平均值。"

1.1 期望的定义

定义

随机变量X的期望:
E(X) = Σ x × P(X = x)
     = 所有可能值 × 对应概率

意义:X的"平均值"

示例:投骰子

骰子:1, 2, 3, 4, 5, 6
每个点数概率:1/6

E(X) = 1×(1/6) + 2×(1/6) + 3×(1/6) + 4×(1/6) + 5×(1/6) + 6×(1/6)
     = (1+2+3+4+5+6) / 6
     = 21 / 6
     = 3.5

期望是3.5(平均点数)

哈吉米:"期望就是加权平均值。"


1.2 期望的重要性质

性质1:期望的线性性

E(X + Y) = E(X) + E(Y)

即使X和Y不独立,这个性质也成立

为什么这个性质重要?

南北绿豆:"因为它让复杂问题变简单。"

示例

2次骰子,点数之和的期望?

方法1:枚举所有36种情况
  (1,1), (1,2), ..., (6,6)
  计算每种情况的概率和点数
  很繁琐

方法2:线性性
  E(第1次 + 第2次) = E(第1次) + E(第2次)
                   = 3.5 + 3.5
                   = 7

简单多了!

哈吉米:"期望可以拆开算,太方便了。"


二、例题1:骰子到达终点的期望步数

问题描述

一个棋盘有n个格子(0到n-1),你在位置0

每次投骰子(1-6点),往前走对应步数

问题:到达位置n-1的期望步数是多少?

示例:
n = 10

期望步数 ≈ ?

哈吉米:"这题怎么做?"

南北绿豆:"用期望DP。"


2.1 状态定义

dp[i]的定义从位置i出发,到达位置n-1的期望步数

为什么这样定义?

阿西噶阿西:"因为从i出发更好推导。"

正推 vs 逆推

正推(从起点出发):
  dp[i] = 从0i的期望步数
  
  难点:到达i可能有很多路径,概率难算

逆推(从终点回推):
  dp[i] = 从i到n-1的期望步数
  
  简单:从i出发,只需考虑下一步的6种情况

哈吉米:"逆推只看下一步,正推要看所有路径,所以逆推简单。"


2.2 状态转移方程

从位置i出发,投骰子

掷到1:到位置i+1,期望步数dp[i+1]
掷到2:到位置i+2,期望步数dp[i+2]
...
掷到6:到位置i+6,期望步数dp[i+6]

每种情况概率1/6

全期望公式:
E(从i到n-1的步数) = 1 + E(下一步后到n-1的步数)
                  = 1 + (1/6)×dp[i+1] + (1/6)×dp[i+2] + ... + (1/6)×dp[i+6]

状态转移方程

dp[i] = 1 + (dp[i+1] + dp[i+2] + ... + dp[i+6]) / 6

特殊情况:
  如果i+k >= n-1,说明一步到达,贡献0

dp[n-1] = 0(终点,不需要步数)

为什么要+1?

南北绿豆:"因为投了1次骰子,步数+1。"

详细推导

E(从i到n-1的总步数) 
= E(这一步) + E(剩余步数)
= 1 + E(从下一个位置到n-1)
= 1 + (1/6)×Σ dp[i+k],k从16

哈吉米:"全期望公式:总期望 = 当前步 + 后续期望。"


2.3 代码实现

Java版本

public double expectedSteps(int n) {
    double[] dp = new double[n];
    dp[n - 1] = 0; // 终点
    
    // 从后往前推
    for (int i = n - 2; i >= 0; i--) {
        double sum = 0;
        int count = 0;
        
        // 投骰子6种情况
        for (int k = 1; k <= 6; k++) {
            if (i + k >= n - 1) {
                count++; // 一步到达,贡献0
            } else {
                sum += dp[i + k];
                count++;
            }
        }
        
        dp[i] = 1 + sum / count;
    }
    
    return dp[0];
}

C++版本

double expectedSteps(int n) {
    vector<double> dp(n, 0);
    dp[n - 1] = 0;
    
    for (int i = n - 2; i >= 0; i--) {
        double sum = 0;
        int count = 0;
        
        for (int k = 1; k <= 6; k++) {
            if (i + k >= n - 1) {
                count++;
            } else {
                sum += dp[i + k];
                count++;
            }
        }
        
        dp[i] = 1 + sum / count;
    }
    
    return dp[0];
}

Python版本

def expectedSteps(n):
    dp = [0.0] * n
    dp[n - 1] = 0
    
    for i in range(n - 2, -1, -1):
        total = 0
        count = 0
        
        for k in range(1, 7):
            if i + k >= n - 1:
                count += 1
            else:
                total += dp[i + k]
                count += 1
        
        dp[i] = 1 + total / count
    
    return dp[0]

时间复杂度:O(n)


三、概率DP vs 期望DP

南北绿豆:"概率DP和期望DP有啥区别?"

3.1 核心区别

类型定义典型问题
概率DPdp[i] = 到达状态i的概率正推:从起点推概率
期望DPdp[i] = 从状态i出发的期望逆推:从终点回推期望

3.2 为什么期望DP要逆推

详细解释

期望DP正推的困难:
  dp[i] = 到达i的期望步数
  
  问题:到达i可能有多条路径,每条概率不同
  E(到达i) = Σ P(路径k) × 步数k
  
  概率P(路径k)难算(要考虑所有前驱)

期望DP逆推:
  dp[i] = 从i出发到终点的期望步数
  
  简单:只看下一步的选择
  E(从i出发) = 1 + Σ P(选择k) × dp[下一步k]
  
  概率P(选择k)通常是已知的(比如1/6

哈吉米:"逆推只看未来(下一步),正推要看过去(所有路径),所以逆推简单。"

南北绿豆:"完全正确!期望DP优先考虑逆推。"


四、全期望公式

南北绿豆:"期望DP的数学基础是全期望公式。"

4.1 全期望公式

定理

E(X) = Σ E(X | Aᵢ) × P(Aᵢ)

其中A₁, A₂, ..., Aₙ是完备事件组

人话解释

总期望 = 各种情况的期望 × 各种情况的概率

应用在骰子问题

E(从i出发的步数) 
= E(掷到1) × P(掷到1) + E(掷到2) × P(掷到2) + ... + E(掷到6) × P(掷到6)
= (1 + dp[i+1]) × 1/6 + (1 + dp[i+2]) × 1/6 + ... + (1 + dp[i+6]) × 1/6
= 1 + (dp[i+1] + dp[i+2] + ... + dp[i+6]) / 6

哈吉米:"全期望公式就是加权平均!"


五、概率DP与期望DP总结

5.1 核心要点

南北绿豆总结:

  1. 概率DP:求到达某状态的概率(正推)
  2. 期望DP:求从某状态出发的期望(逆推)
  3. 全期望公式:E(X) = Σ E(X|A) × P(A)
  4. 期望线性性:E(X+Y) = E(X) + E(Y)

5.2 解题步骤

阿西噶阿西

1. 判断是概率还是期望
2. 定义状态dp[i]
3. 找状态转移(用全期望公式)
4. 确定边界条件
5. 确定推导方向(正推/逆推)

5.3 识别技巧

南北绿豆

  • 看到期望、平均,想期望DP
  • 看到概率、可能性,想概率DP
  • 看到随机、"骰子,想概率/期望DP

哈吉米:"概率问题也能用DP,数学真美妙。"


参考资料

  • 《概率论与数理统计》- 盛骤
  • 《算法竞赛进阶指南》- 李煜东