关于概率dp的个人理解与总结

本文介绍了概率动态规划(概率dp)的基本思想和应用,包括如何求解概率和期望问题。通过正推和逆推方法,解析了求概率时当前状态由前一状态转移而来,以及求期望时考虑后续状态对当前期望的影响。文章列举了多个实例,如poj 2096、hdu 3853等,探讨了如何处理期望问题的环状结构,以及如何利用记忆化搜索和矩阵快速幂优化解题过程。

首先,概率dp主要解决的是关于概率问题和期望问题的求解。

难点和普通dp一样在于dp[i][j][k]的维数控制和含义,其实就是转移方程的构建。

然后一般地,求概率是正推、求期望是逆推。(开始的很多状态不可能发生概率为0,最后的状态出口期望为0)

对于求概率当前点的概率是由前面能到达当前点的点乘上到达当前点的概率得到的。

也就是dp[i]=Σ(dp[j]*p[j][i])  i是当前点、j是前面的点。

对于求期望当前点的期望是由当前点所能到达的点得到的。(注意下,对应的概率是当前点到达之后点的概率,因为你要到达后面的点后面的点才能传递给你期望!)

也就是E[i]=Σ((E[j]+k)*p[i][j])  i是当前点、j是当前点所能到达的点,k是所需的期望值。

然后就是对于期望的话,如果成环的话数据范围小的话可以用高斯消元解决(之前的博文提到),如果范围大就要推导公式了(后面的题目有提到)。


poj  2096 Collecint Bugs 

dp求期望入门题。

题意,思路,公式引用别人的:http://www.cnblogs.com/kuangbin/archive/2012/10/02/2710606.html

dp求期望
逆着递推求解
题意:(题意看题目确实比较难道,n和s都要找半天才能找到)
   一个软件有s个子系统,会产生n种bug
   某人一天发现一个bug,这个bug属于一个子系统,属于一个分类
   每个bug属于某个子系统的概率是1/s,属于某种分类的概率是1/n
   问发现n种bug,每个子系统都发现bug的天数的期望。

求解:
         dp[i][j]表示已经找到i种bug,j个系统的bug,达到目标状态的天数的期望
         dp[n][s]=0;要求的答案是dp[0][0];
         dp[i][j]可以转化成以下四种状态:
              dp[i][j],发现一个bug属于已经有的i个分类和j个系统。概率为(i/n)*(j/s);
              dp[i][j+1],发现一个bug属于已有的分类,不属于已有的系统.概率为 (i/n)*(1-j/s);
              dp[i+1][j],发现一个bug属于已有的系统,不属于已有的分类,概率为 (1-i/n)*(j/s);
              dp[i+1][j+1],发现一个bug不属于已有的系统,不属于已有的分类,概率为 (1-i/n)*(1-j/s);
        整理便得到转移方程
代码:

#include"cstdlib"
#include"cstdio"
#include"cstring"
#include"cmath"
#include"queue"
#include"algorithm"
#include"iostream"
#define eps 1e-5
using namespace std;
double dp[1020][1020];
int main()
{
    int n,s;
    while(cin>>n>>s)
    {
        memset(dp,0,sizeof(dp));
        for(int i=n; i>=0; i--)
        {
            for(int j=s; j>=0; j--)
            {
                if(i==n&&j==s) continue;
                double tep=1.0;
                if(i<n) tep+=(n*1.0-i)*j/(n*s)*dp[i+1][j];
                if(j<s) tep+=(s*1.0-j)*i/(n*s)*dp[i][j+1];
                if(i<n&&j<s) tep+=(n*1.0-i)*(s*1.0-j)/(n*s)*dp[i+1][j+1];
                dp[i][j]=tep/(1-(i*j*1.0)/(s*n));
            }
        }
        printf("%.4f\n",dp[0][0]);
    }
    return 0;
}


类似的简单题:

hdu 3853     注意停留原地的情况,应该跳过不处理。还有一点走一步的期望是2。
hdu 4405     处理一下连续移动的情况
SGU 495      用概率求期望
CF 148D   考虑下边界就OK了,方程很好推


zoj 3640 Help Me Escape

题意:

一只吸血鬼,有n条路给他走,每次他随机走一条路,

每条路有个限制,如果当时这个吸血鬼的攻击力大于等于某个值,那么就会花费t天逃出去。

否则,花费1天的时间,并且攻击力增加,问他逃出去的期望天数。

思路:

方程很好像  dp[i] 有i点战斗力逃出去的期望

那么如果  x>c[i]时 dp[i]=(1.0/n)*Σt[i]

否则   dp[i]=(1.0/n)*Σ(dp[i+c[i]]+1)

因为很多点会被重复用,所以写成记忆化搜索。

还有一个要注意的,t[i]是向下取整的。

代码:

#include"cstdlib"
#include"cstdio"
#include"cstring"
#include"cma
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值