简单的概率dp概述

好久没有写过了,再回来填一填坑。

以前一直以为期望与概率是数学版块里的,结果当它每次和dp一起出现之后,才发现它是数学和dp的结合。而且对于不理解期望概率是啥的萌新表示,真的是连暴力都不会打。而且令人窒息的是这类题的样例也不是很好算,如果不理解题意,真的连样例都都手算不出来。当然这样的好处是一般样例过了就基本上A了。
所以本着学会打暴力的思想,我们学一学概率dp。
先讲一下什么是期望&概率。

首先概率数学上都学过,简单(度娘)来说就是:对于事件A,它的概率定义为: P(A)=mn P ( A ) = m n

,其中 n n 表示该试验中所有可能出现的基本结果的总数目。m表示事件A包含的试验基本结果数。
值得一提的是,在oi当中因为大多数题目中 n n m是有限的,所以我们可以通过枚举 n n m的个数来计算答案。(但是这样的复杂度通常是 2n 2 n 的)
期望相较于概率在数学出现的不那么频繁,但是在oi中期望真的是概率的好几倍。度娘:在概率论和统计学中,数学期望(mean)(或均值,亦简称期望)是试验中每次可能结果的概率乘以其结果的总和,是最基本的数学特征之一。它反映随机变量平均取值的大小。
用公式表达就是对于事件 i i 定义它的权值为W(i),那么结果的期望则是: sumni=1WiPi s u m i = 1 n W ( i ) ∗ P ( i )

介绍完概念,我们先来看一道题:CF148D Bag of mice
由于codeforces是英文的,就直接贴洛谷上有翻译的。
在概率题当中,推式子是很重要的,一般式子推出来就做了一大半了。(如图) fi,j,A f i , j , A 到达表示还剩 i i 个白色,j个黑色且 A A 为先手的状态的概率。(B同理)

这里写图片描述

其实仔细观察就可以发现f数组的连边其实是一条DAG,所以我们想到了递推。然而这个题还有一个问题就是在DAG上求拓扑序。由于我比较懒,就使用了记忆化搜索。但是在记忆化搜索中, f f 不再表示起点到达它的概率,而变成了从它开始A获胜的概率。实际上这道题就又变成了倒推。还有一个坑点是int转double(可能就我会掉坑里)
贴一下代码:

#include<iostream>  
#include<cstdio>  
#include<cstring>  
#define A 0  
#define B 1   
using namespace std;  
double f[1005][1005][2];  
bool vis[1005][1005][2];  
int n,m;  

double dp(int w,int b,int p)  
{  
    if(vis[w][b][p]==1) return f[w][b][p];  
    vis[w][b][p]=1;  
    if(w==0) return f[w][b][p]=0;  
    if(p==A)  
    {  
        f[w][b][p]+=(double)w/(w+b);  
        if(b-1>=0)  
          f[w][b][p]+=(double)b/(w+b)*dp(w,b-1,B);  
        return f[w][b][p];  
    }  
    if(p==B)  
    {  
      if(b-1>=0)  
        f[w][b][p]+=(double)w/(w+b-1)*dp(w-1,b-1,A);  
      if(b-2>=0)  
        f[w][b][p]+=(((double)b-1)/(w+b-1))*dp(w,b-2,A);  
      return f[w][b][p]=(double)b/(w+b)*f[w][b][p];  
    }  
}  

int main()  
{  
    //cout<<(double)((2-1)/(1+2-1))*1.0;  
    scanf("%d%d",&n,&m);  
    printf("%.9f",dp(n,m,A));  
}   

做完概率板子,我们来看一看期望:对于一个dag,求它从起点走到终点的期望步数。额,只记得题,不知道在哪儿了。
不过这都没有关系,我们来口头AC一下。
这里写图片描述
貌似就过了,不过。。。
这tm是对的?我最远才走3步好吧。
刚学期望概率的时候,总有人说,递推要倒退,或者有人说期望倒退,概率正推。这是为什么呢。
观察上图我们发现,我们想用每一个点的值来表示起点到它的概率乘以权值,简单说就是期望步数。但是我们却无法转移这个值,因为我们根本不知道下一步的1应该乘以什么样的权值加入下一个点的期望。而且这样做法有一个致命的问题就是一条路径无法到达终点时,这个方法就没有了意义。
但并不是说不能倒退,既然我们不知道概率,那我们为什么不在算期望的同时计算概率呢?这样的确可以正推。
所以我们不选择正推的方式是因为有点麻烦。
于是就有了倒推,同上,f(u)表示 u u <script type="math/tex" id="MathJax-Element-35">u</script>到达终点的期望步数。
这里写图片描述
这样为什么是对的,我们考虑一下,一个点所到达的所有儿子可以向它转移,而且我们知道这个转移的概率,就是加权求和。
最后一点,讲到倒推,记忆化搜索确实是一个神器,虽然正向连边,但是记忆化搜索实际是在回溯是计算值,正好是倒推。而且在一些正推难以找到递推规律的,记忆化搜索也可以解决。这样我们并不需要什么额外操作就可以实现算法,何乐而不为呢?

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值