简单期望DP

期望dp

数学期望是指离散型随机变量的平均值。即考虑所有情况结果的平均值,它等于每种情况的概率与该情况下的结果的乘积之和。

比如一枚硬币,有正反两面,丢出正面或反面的概率相等,请问丢出正面的期望次数。

直觉告诉我们,需要丢两次。因为丢出正面的概率为12\frac{1}{2}21,所以,需要丢出两次。

这是最简单的情形。

又比如掷一颗骰子,骰子有6个面,出现每个面的概率相等,请问丢出1的期望次数。

显然,直觉告诉我们,需要丢出6次。因为丢出1的概率是16\frac{1}{6}61.

是不是期望次数就是概率的倒数呢?

独立随机试验下,首次出现某个事件的期望试验次数等于出现该事件的概率的倒数。

而期望并不仅仅指事件,也可以是针对其他变量的期望。期望,就是我们要求的值在所有情况下的平均值。比如,丢一枚硬币,正反面等概率出现,如果丢出正面,你得到1元,如果丢出反面,你得到0元。请问你丢一次期望多少元?

那么答案是0.5元。12∗1+12∗0=0.5\frac{1}{2}*1+\frac{1}{2}*0=0.5211+210=0.5

在大多数情况下,期望都应该用其定义式或递推方程来计算。

我们来看如何用期望的定义来计算以上最简单的情形。

例1

丢一枚硬币,出现正面的期望次数。

分析:

统计所有情况下花掉的次数。第一次就丢出正面,花费1次;第二次才丢出正面,花费2次;第三次丢出正面,花费3次,…\dots

g=12∗1+14∗2+⋯+i2i(1)g=\frac{1}{2}*1+\frac{1}{4}*2+\dots+\frac{i}{2^i} \tag{1}g=211+412++2ii(1)

2∗g=1+1+34+⋯+i2i−1(2)2*g=1+1+\frac{3}{4}+\dots+\frac{i}{2^{i-1}} \tag{2}2g=1+1+43++2i1i(2)

(2)-(1),可得:

12g=1+12+14+⋯+12i−1=1\frac{1}{2}g=1+\frac{1}{2}+\frac{1}{4}+\dots+\frac{1}{2^{i-1}} = 121g=1+21+41++2i11=1

g=2g = 2g=2.

例2

丢一颗骰子,出现1的期望次数。

g=1∗16+2∗56∗16+⋯+56i−1∗16∗ig=1*\frac{1}{6}+2*\frac{5}{6}*\frac{1}{6}+\dots+{\frac{5}{6}}^{i-1}*\frac{1}{6}*ig=161+26561++65i161i

56g=1∗16∗56+2∗562∗16+⋯+56i∗16\frac{5}{6}g=1*\frac{1}{6}*\frac{5}{6}+2*\frac{5}{6}^2*\frac{1}{6}+\dots+\frac{5}{6}^{i}*\frac{1}{6}65g=16165+265261++65i61

g−56g=16∗∑i=1∞56i−1g-\frac{5}{6}g=\frac{1}{6}*\sum_{i=1}^\infin\frac{5}{6}^{i-1}g65g=61i=165i1

g=6g=6g=6

也可以用递推的方式来求,这是更加简便的方法。

例3

丢一枚硬币,出现正面的期望次数。

xxx为丢出正面的期望次数,丢一次以后,有12\frac{1}{2}21的概率回到原状态,仍然是xxx, 也有12\frac{1}{2}21的概率成功,成功了就不需要再丢了。刚才花费了一次。所以有以下的递推式:

x=12x+12∗0+1x=\frac{1}{2}x+\frac{1}{2}*0+1x=21x+210+1

解得x=2x=2x=2

又如丢骰子,丢出每个面的概率都是16\frac{1}{6}61

设丢出1的期望次数为xxx, 丢1次以后,有16\frac{1}{6}61的概率成功,不需要再丢了;有56\frac{5}{6}65的概率未成功,即回到原状态,仍然期望丢xxx次。而刚才花费了1次,所以,有以下的递推式:

x=56∗x+16∗0+1x = \frac{5}{6}*x+\frac{1}{6}*0+1x=65x+610+1

解得x=6x=6x=6.

例4

有n种牌,每种牌各1张,你取到每种牌都是等概率的,你取一张牌,记下该牌的种类,然后放回去。请问你记下所有的种类的牌期望要取多少次?

分析:

f[i]f[i]f[i]表示当前已经取到了i种牌,最后离成功(取到所有种类的牌)所期望的次数。

显然f[n]=0f[n]=0f[n]=0.

f[i]=in∗f[i]+n−in∗f[i+1]+1f[i] = \frac{i}{n}*f[i]+\frac{n-i}{n}*f[i+1]+1f[i]=nif[i]+nnif[i+1]+1

f[i]=f[i+1]+nn−if[i]=f[i+1]+\frac{n}{n-i}f[i]=f[i+1]+nin

这个题也适用于前面的简单的情形,即期望的次数是概率的倒数,因为一次取牌事件发生后,要么成功,要么回到原状态。取牌事件之间也是独立的。

即当前有i张牌,你有n−in\frac{n-i}{n}nni的概率取到1张新牌,有in\frac{i}{n}ni的概率取到一张之前的牌,仍然回到原状态。即从iii张牌到i+1i+1i+1张牌,只有n−in\frac{n-i}{n}nni的概率成功,这一步需要花费的期望次数为n−in\frac{n-i}{n}nni.

所以有:

f[i]=f[i+1]+n−inf[i]=f[i+1]+\frac{n-i}{n}f[i]=f[i+1]+nni

一种错误的递推方式:

f[i]f[i]f[i]表示从取到iii张牌期望的取牌次数,考虑最近一次的取牌操作,有in\frac{i}{n}ni的概率取得的是旧牌,有n−i+1n\frac{n-i+1}{n}nni+1的概率取得新牌。刚才的取牌花掉了一次操作,所以有下式:

f[i]=f[i]∗in+f[i−1]∗n−i+1n+1f[i] = f[i]*\frac{i}{n} + f[i-1]*\frac{n - i + 1}{n} + 1f[i]=f[i]ni+f[i1]nni+1+1

f[1]=1f[1]=1f[1]=1

此处的问题主要是f[i]f[i]f[i]的意义与题意不符。按题意描述,如果取到了nnn种牌,则不应再取了。而此处的f[n]f[n]f[n]取到了nnn种牌后,仍然可能取牌。

所以,此处求出的f[n]f[n]f[n]并不能表示题目中期望次数。

例5.
题意:一个图有n个顶点,现在你站在顶点1处。开始时,图中没有边。

你可以重复以下操作:

  • 从n个点中选择一个点(可以包含你当前所在的点),每个点都有1N\frac{1}{N}N1的概率被选中。每次选择都是独立的,和上一次选择无关。

  • 在你当前站立的点和选择的点之间连一条边,然后移动到你选择的点上。
    求图变为连通图时,期望的操作次数。

数据规模

2≤N≤1052 \leq N \leq 10^52N105

这题与例4完全相同。

例6 . csp初赛题

现有一只青蛙,初始时在 n 号荷叶上。当它某一时刻在 k 号荷叶上时,下一时刻将等概 率地随机跳到 1, 2, …, k 号荷叶之一上,直至跳到 1 号荷叶为止。当 n = 2 时,平均一共 跳 2 次;当 n = 3 时,平均一共跳 2.5 次。则当 n = 5 时,平均一共跳_________次。

分析:设f[i]f[i]f[i]表示青蛙在iii号荷叶上时,要跳到1号荷叶上的期望次数。

f[i]=f[i]∗1i+f[i−1]∗1i+⋯+f[1]∗1i+1f[i]=f[i]*\frac{1}{i}+f[i-1]*\frac{1}{i}+\dots+f[1]*\frac{1}{i} + 1f[i]=f[i]i1+f[i1]i1++f[1]i1+1

显然f[1]=0f[1] = 0f[1]=0

根据递推式,可以求出:f[2]=2,f[3]=2.5,f[4]=176,f[5]=3712f[2] = 2, f[3] = 2.5, f[4] = \frac{17}{6},f[5] = \frac{37}{12}f[2]=2,f[3]=2.5,f[4]=617,f[5]=1237

例7. 涂格子

n个格子,每次随机涂一个,求涂m次后期望涂色格子数。

分析:

f[i]f[i]f[i]表示涂iii次后期望涂多少个格子。

f[i]=f[i−1]+n−f[i−1]nf[i]=f[i-1]+\frac{n-f[i-1]}{n}f[i]=f[i1]+nnf[i1]

例8. 涂格子

nnn个格子,每次随机选一个格子涂色,第iii个格子被选到的概率为pip_ipi, (∑pi=1)(\sum_{p_i}=1)(pi=1),求涂完所有格子的期望次数。

数据规模:n≤20n \leq 20n20
分析:

因为每个格子的概率不一样,所以不能以格子数量来作为状态,而以涂色格子的二进制state来表示状态。

f[state]f[state]f[state]涂到的格子为statestatestate时,到最终状态期望的次数。

则有f[state]=∑i=0n−1f[state∣(1<<i)]∗pi+1f[state] =\sum_{i=0}^{n-1} f[state |(1<<i)]*p_i+1f[state]=i=0n1f[state(1<<i)]pi+1

例9. 亚瑟王的生日庆典(poj3682)

题意:亚瑟王掷一枚硬币,正面朝上的概率为ppp,反面朝上的概率为1−p1-p1p。现在亚瑟王要举办生日庆典,举办的天数通过掷硬币确定。他每天掷有一次硬币,直到掷出k次正面朝上,就结束。第iii天的花费为2∗i−12*i-12i1。问:

期望要掷多少枚硬币才能达到kkk次正面朝上,以及达到kkk次正面朝上时的花费。

分析:

f[i]f[i]f[i]表示已经掷出iii次正面朝上,要完成k次还需要的期望次数。则有:

f[i]=f[i+1]∗p+f[i]∗(1−p)+1f[i]=f[i+1]*p+f[i]*(1-p)+1f[i]=f[i+1]p+f[i](1p)+1

f[i]=f[i+1]+1/pf[i] = f[i+1]+1/pf[i]=f[i+1]+1/p

则有:f[0]=n/pf[0]=n/pf[0]=n/p

g[i]g[i]g[i]表示已经掷出iii次正面朝上,要完成kkk次还需要的期望花费。注意:这个花费按照时间倒流的方式计算也是正确的。

g[i]=g[i+1]∗p+g[i]∗(1−p)+2∗f[i]−1g[i]=g[i+1]*p+g[i]*(1-p)+2*f[i]-1g[i]=g[i+1]p+g[i](1p)+2f[i]1

推出:g[0]=k∗(k+1)−kpp2g[0]=\frac{k*(k+1)-kp}{p^2}g[0]=p2k(k+1)kp

#include<bits/stdc++.h>
int main()
{
    int k;
    double p,res1,res2;
 
    while(scanf("%d%lf",&k,&p)&&k)
    {
        res1 = k/p;
        res2 = k*(k+1)/(p*p)-res1;
        printf("%.3lf %.3lf\n",res1,res2);
    }
}
### 蓝桥杯竞赛中的期望动态规划(Expectation DP) #### 什么是期望动态规划? 期望动态规划是一种特殊的动态规划形式,通常用于解决概率和统计相关的问题。其核心在于通过状态转移方程计算某个事件发生的期望值。这类问题的特点是存在多种可能的状态变化路径,并且每种路径都有一定的概率发生。 在蓝桥杯竞赛中,期望动态规划题目往往涉及随机过程、决策优化以及条件概率等内容。以下是针对此类问题的一些通用解题思路: --- #### 解题思路 1. **定义状态** 定义清晰的状态变量 \( dp[i] \),表示当前处于某种状态下所对应的期望值或最优值。例如,在某些问题中,\( dp[i] \) 可能代表从第 \( i \) 步到目标状态的期望步数[^4]。 2. **建立状态转移方程** 根据问题描述,分析如何从前一状态转移到下一状态。对于期望动态规划而言,状态转移方程一般会涉及到加权平均的形式,即考虑不同分支的概率及其对应的结果。例如: \[ dp[i] = p_1 \cdot f(dp[j]) + p_2 \cdot g(dp[k]) \] 其中 \( p_1, p_2 \) 是相应分支的发生概率,而 \( f(\cdot), g(\cdot) \) 表示具体的转换逻辑[^5]。 3. **初始化边界条件** 明确初始状态下的期望值或者已知结果。这一步非常重要,因为它是整个递推的基础。例如,如果到达终点时的期望值为零,则可以直接设置 \( dp[n] = 0 \)[^6]。 4. **逆向思考** 很多时候,正向求解可能会遇到循环依赖等问题,因此采用倒序的方式更容易实现。比如先从最终状态出发逐步向前更新各个中间节点的数据[^7]。 5. **注意精度控制** 鉴于浮点运算容易引发误差累积现象,在编写程序过程中应特别留意数值处理细节,必要情况下可适当调整比较阈值来规避潜在风险[^8]。 --- #### 示例代码 下面给出一个简单的例子——掷骰子游戏,假设每次投掷六面均匀骰子直到累计得分达到指定分数为止,问所需的平均次数是多少? ```cpp #include <bits/stdc++.h> using namespace std; const int MAX_SCORE = 1e5; double dp[MAX_SCORE + 1]; // 存储每个得分为i时还需要多少次才能完成任务 int main(){ memset(dp, 0, sizeof(dp)); int target_score; cin >> target_score; for(int s=target_score-1 ;s>=0;s--){ double sum_prob=0,sum_expect=0; for(int roll=1;roll<=6 && (s+roll)<=target_score;roll++){ sum_prob += 1/6.0; sum_expect += ((dp[s+roll]+1)*1/6.0); } if(sum_prob>0){ dp[s]=sum_expect / sum_prob; }else{ dp[s]=(double)(MAX_SCORE*10); // 设置极大值作为不可达标志 } } printf("%.9f\n",dp[0]); } ``` 上述代码片段展示了如何运用DP表记录各阶段所需预期操作数目并据此得出全局解决方案的过程[^9]。 --- #### 注意事项 尽管以上方法适用于大多数常规场景,但在实际比赛中还需灵活应对各种特殊情况。例如当面临复杂约束条件或是非线性关系时,单纯依靠基础模型或许难以满足需求,此时则需引入更多高级算法加以辅助[^10]。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值