引言
在动态规划的广阔领域中,概率动态规划(Probability DP)专门用于解决涉及随机性和不确定性的问题。当我们需要计算某种结果的期望值、概率分布或最优决策时,概率DP往往能提供优雅而高效的解决方案。
概率DP的基本概念
什么是概率动态规划
概率动态规划(Probability DP)是动态规划的一个分支,专门用于解决涉及随机性和概率的问题。在传统动态规划中,状态转移是确定性的,而在概率DP中,状态转移是随机的,需要考虑各种可能性及其发生的概率。
概率DP通常用于解决以下类型的问题:
- 期望值计算:计算某个随机过程的期望结果,如期望步数、期望得分等。
- 概率计算:计算某个事件发生的概率,如胜利概率、到达特定状态的概率等。
- 最优决策:在随机环境中找到最优策略,最大化期望收益或最小化期望损失。
期望值的基本性质
在深入概率DP之前,我们需要了解期望值的基本性质,这些性质在解题过程中非常有用:
- 线性性质:对于随机变量X和Y,E(X + Y) = E(X) + E(Y)
- 常数倍性质:对于随机变量X和常数c,E(cX) = cE(X)
- 独立性质:如果X和Y是独立的随机变量,则E(XY) = E(X)E(Y)
这些性质使我们能够将复杂的期望计算分解为更简单的子问题,这正是动态规划的核心思想。
概率DP的基本框架
概率DP的基本框架通常包括以下几个步骤:
- 定义状态:根据问题特点定义状态,通常包括当前的位置、已经完成的任务、剩余的资源等。
- 确定状态转移:分析从当前状态可能转移到哪些状态,以及每种转移发生的概率。
- 建立状态转移方程:根据概率论的知识,建立状态之间的数学关系。
- 确定边界条件:确定一些基本状态的值,作为递推的起点。
- 求解:通过递推或递归求解所有需要的状态值。
在概率DP中,状态转移方程通常有两种形式:
- 正向递推:从初始状态开始,计算到达各个状态的概率。适用于求解概率分布问题。
- 反向递推:从目标状态开始,计算从各个状态到达目标的期望步数或期望代价。适用于求解期望值问题。
值得注意的是,在期望DP问题中,我们经常需要解一个方程组来得到期望值,这是因为当前状态的期望值可能依赖于自身。
期望值计算问题
期望DP的基本思路
在期望DP中,我们通常关注的是某个随机过程的期望结果,如期望步数、期望得分等。解决这类问题的基本思路是:
- 定义状态:设dp[i]表示从状态i到达目标状态的期望值(步数、代价等)。
- 建立方程:根据状态i可能转移到的下一个状态j及其概率p_j,建立方程:
dp[i] = ∑(p_j * (dp[j] + cost_ij))
其中cost_ij是从状态i转移到状态j的代价。 - 解方程:通常从目标状态开始,反向求解各个状态的期望值。
需要注意的是,在期望DP中,我们经常会遇到方程中包含未知数自身的情况,这时需要通过代数方法解方程。
经典例题:掷骰子问题
问题描述:有一个n面的骰子,每次掷骰子时,每个面朝上的概率相等。问期望掷多少次骰子,才能使得所有面都至少出现一次?
解题思路:
-
定义状态:设dp[i]表示已经出现了i种不同点数,期望还需要掷多少次骰子才能使所有n种点数都出现。
-
建立方程:当已经出现了i种不同点数时,下一次掷骰子有两种可能:
- 掷出已经出现过的点数,概率为i/n,状态保持不变。
- 掷出新的点数,概率为(n-i)/n,状态变为dp[i+1]。
因此,方程为:dp[i] = 1 + (i/n) * dp[i] + ((n-i)/n) * dp[i+1]
化简得:dp[i] = 1 + dp[i+1] * (n-i)/i
-
边界条件:dp[n] = 0,表示已经出现了所有n种点数,不需要再掷骰子。
-
求解:从dp[n-1]开始,反向计算到dp[0],即为答案。
def expected_throws(n):
dp = [0] * (n + 1)
for i in range(n - 1, 0, -1):
dp