注意:在概率DP中求期望要逆着推,求概率要正着推

概率DP求期望:

链接: http://acm.hdu.edu.cn/showproblem.php?pid=4405

dp[ i ]表示从i点走到n点的期望,在正常情况下i点可以到走到i+1,i+2,i+3,i+4,i+5,i+6 点且每个点的概率都为1/6

所以dp[i]=(dp[i+1]+dp[i+2]+dp[i+3]+dp[i+4]+dp[i+5]+dp[i+6])/6  + 1(步数加一)

而对于有跳跃的点直接为dp[a]=dp[b];

</pre><pre code_snippet_id="436469" snippet_file_name="blog_20140727_1_1601949" name="code" class="cpp">
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=100000+10;
double dp[maxn];
int vist[maxn];
int main()
{
int n,m;
while(cin>>n>>m)
{
if(n==0&&m==0)
break;
memset(vist,-1,sizeof(vist));
memset(dp,0.0,sizeof(dp));
int a,b;
while(m--)
{
cin>>a>>b;
vist[a]=b;
}
for(int i=n-1;i>=0;i--)
{
if(vist[i]!=-1) dp[i]=dp[vist[i]];
else
{
dp[i]=(dp[i+1]+dp[i+2]+dp[i+3]+dp[i+4]+dp[i+5]+dp[i+6])/6.0+1;
}
}
printf("%.4lf\n",dp[0]);
}
return 0;
}

直接推到公式求期望:

链接:http://acm.hdu.edu.cn/showproblem.php?pid=3853

题目大意

有一个人被困在一个 R*C(2<=R,C<=1000) 的迷宫中,起初他在 (1,1) 这个点,迷宫的出口是 (R,C)。在迷宫的每一个格子中,他能花费 2 个魔法值开启传送通道。假设他在
(x,y) 这个格子中,开启传送通道之后,有 p_lift[i][j] 的概率被送到 (x,y+1),有 p_down[i][j] 的概率被送到 (x+1,y),有 p_loop[i][j] 的概率被送到 (x,y)。问他到出口需要花费的魔法值的期望是多少。

做法分析

令:f[i][j] 表示从 (i,j) 这个点到出口 (R,C) 花费的魔法值的期望。

那么,我们有:

f[i][j] = p_loop[i][j]*f[i][j] + p_left[i][j]*f[i][j+1] + p_down[i][j]*f[i+1][j]

移项可得:

(1-p_loop[i][j])*f[i][j] = p_left[i][j](f[i][j+1] + p_down[i][j]*f[i+1][j]

于是我们可以倒着递推了

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=1000+10;
double dp[maxn][maxn];
typedef struct Mat
{
double a,b,c;
};
Mat p[maxn][maxn];
int main()
{
int r,c;
while(scanf("%d%d",&r,&c)!=EOF)
{
if(r==0&&c==0) break;
for(int i=0;i<r;i++)
for(int j=0;j<c;j++)
scanf("%lf%lf%lf",&p[i][j].a,&p[i][j].b,&p[i][j].c);
memset(dp,0.0,sizeof(dp));
for(int i=r-1;i>=0;i--)
for(int j=c-1;j>=0;j--)
{
if(i==r-1&&j==c-1) continue;
if(1-p[i][j].a==0) continue;
dp[i][j]=(1+dp[i][j+1]*p[i][j].b+dp[i+1][j]*p[i][j].c)/(1.0-p[i][j].a);
}
printf("%.3lf\n",2*dp[0][0]);
}
return 0;
}

直接推倒公式求期望

链接:http://poj.org/problem?id=2096

  1. dp求期望的题。
  2. 题意:一个软件有s个子系统,会产生n种bug。
  3. 某人一天发现一个bug,这个bug属于某种bug,发生在某个子系统中。
  4. 求找到所有的n种bug,且每个子系统都找到bug,这样所要的天数的期望。
  5. 需要注意的是:bug的数量是无穷大的,所以发现一个bug,出现在某个子系统的概率是1/s,
  6. 属于某种类型的概率是1/n。
  7. 解法:
  8. dp[i][j]表示已经找到i种bug,并存在于j个子系统中,要达到目标状态的天数的期望。
  9. 显然,dp[n][s]=0,因为已经达到目标了。而dp[0][0]就是我们要求的答案。
  10. dp[i][j]状态可以转化成以下四种:
  11. dp[i][j]    发现一个bug属于已经找到的i种bug和j个子系统中
  12. dp[i+1][j]  发现一个bug属于新的一种bug,但属于已经找到的j种子系统
  13. dp[i][j+1]  发现一个bug属于已经找到的i种bug,但属于新的子系统
  14. dp[i+1][j+1]发现一个bug属于新的一种bug和新的一个子系统
  15. 以上四种的概率分别为:
  16. p1 =     i*j / (n*s)
  17. p2 = (n-i)*j / (n*s)
  18. p3 = i*(s-j) / (n*s)
  19. p4 = (n-i)*(s-j) / (n*s)
  20. 又有:期望可以分解成多个子期望的加权和,权为子期望发生的概率,即 E(aA+bB+...) = aE(A) + bE(B) +...
  21. 所以:
  22. dp[i,j] = p1*dp[i,j] + p2*dp[i+1,j] + p3*dp[i,j+1] + p4*dp[i+1,j+1] + 1;
  23. 整理得:
  24. dp[i,j] = ( 1 + p2*dp[i+1,j] + p3*dp[i,j+1] + p4*dp[i+1,j+1] )/( 1-p1 )
  25. = ( n*s + (n-i)*j*dp[i+1,j] + i*(s-j)*dp[i,j+1] + (n-i)*(s-j)*dp[i+1,j+1] )/( n*s - i*j )
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=1000+10;
double dp[maxn][maxn];
int main()
{
int n,s;
cin>>n>>s;
dp[n][s]=0.0;
for(int i=n;i>=0;i--)
for(int j=s;j>=0;j--)
{
if(i==n&&j==s) continue;
dp[i][j]=(n*s+(n-i)*j*dp[i+1][j]+i*(s-j)*dp[i][j+1]+(s-j)*(n-i)*dp[i+1][j+1])/(n*s-i*j);
}
printf("%.4lf\n",dp[0][0]);
return 0;
}

先求概率在通过概率从求期望类型

链接:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2422

题解:《算法竞赛入门经典训练指南》141~142

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
const int maxn=110;
double dp[maxn][maxn];
int main()
{
int t;
scanf("%d",&t);
for(int cas=1;cas<=t;cas++)
{
int a,b,n;
scanf("%d/%d%d",&a,&b,&n);
double p=(double)a/b;
memset(dp,0.0,sizeof(dp));
dp[0][0]=1.0;
dp[0][1]=0.0;
for(int i=1;i<=n;i++)
for(int j=0;b*j<=a*i;j++)
{
dp[i][j]=dp[i-1][j]*(1-p);
if(j) dp[i][j]+=dp[i-1][j-1]*p;
}
double Q=0.0;
for(int i=0;b*i<=a*n;i++)
Q+=dp[n][i];
printf("Case #%d: %d\n",cas,(int)(1/Q));
}
return 0;
}

DP专题之概率DP的更多相关文章

  1. DP专题·四(树形dp)

    1.poj 115 TELE 题意:一个树型网络上有n个结点,1~n-m为信号传送器,n-m+1~n为观众,当信号传送给观众后,观众会付费观看,每铺设一条道路需要一定费用.现在求以1为根,使得收到观众 ...

  2. AIM Tech Round 3 (Div. 1) (构造,树形dp,费用流,概率dp)

    B. Recover the String 大意: 求构造01字符串使得子序列00,01,10,11的个数恰好为$a_{00},a_{01},a_{10},a_{11}$ 挺简单的构造, 注意到可以通 ...

  3. Codeforces123E. Maze【树形dp】【概率dp】【证明题】

    LINK 题目大意 一棵树,上面的每个点都有一定概率成为起点和终点 从起点出发,随机游走,并按照下列规则统计count: DFS(x) if x == exit vertex then finish ...

  4. hdu3076—概率dp

    hdu3076-概率dp 标签 : 概率dp 题目链接 题意: 2个人分别有AB的血数,轮流扔骰子,数小的自减一血,平的不变,谁先到减0, 谁输,问A赢的概率. 题解: dp[i][j]表示的是第一个 ...

  5. 树形dp专题总结

    树形dp专题总结 大力dp的练习与晋升 原题均可以在网址上找到 技巧总结 1.换根大法 2.状态定义应只考虑考虑影响的关系 3.数据结构与dp的合理结合(T11) 4.抽直径解决求最长链的许多类问题( ...

  6. 概率dp作业

    概率dp特征: 概率DP一般求的是实际结果,在DP过程中,当前状态是由所有子状态的概率共同转移而来,所以概率DP只是利用了DP的动态而没有规划(即只需转移无需决策).-------qkoqhh A - ...

  7. UESTC 2015dp专题 F 邱老师看电影 概率dp

    邱老师看电影 Time Limit: 20 Sec  Memory Limit: 256 MB 题目连接 http://acm.uestc.edu.cn/#/contest/show/65 Descr ...

  8. 【专题】概率期望DP

    11.22:保持更新状态:主要发一些相关的题目和个人理解 (P.S.如果觉得简单,可以直接看后面的题目) upd 11.30 更完了 [NO.1] UVA12230 Crossing Rivers  ...

  9. DP专题训练之HDU 2955 Robberies

    打算专题训练下DP,做一道帖一道吧~~现在的代码风格完全变了~~大概是懒了.所以.将就着看吧~哈哈 Description The aspiring Roy the Robber has seen a ...

随机推荐

  1. 【java】基础语法

    集合   单线程 并发 Lists ArrayList——基于泛型数组 LinkedList——不推荐使用 Vector——已废弃(deprecated) CopyOnWriteArrayList—— ...

  2. PTA 03-树3 Tree Traversals Again (25分)

    题目地址 https://pta.patest.cn/pta/test/16/exam/4/question/667 5-5 Tree Traversals Again   (25分) An inor ...

  3. Excel数据导入Sql Server出现Null(转)

    Excel文件: 序号 姓名 内部电话 住址 1 小李 1234 …… 2 小王 5678 …… 3 小张 2345(国内长途) …… …… …… …… …… 如上结构的Excel文件,用SQL Se ...

  4. POJ 3680: Intervals【最小费用最大流】

    题目大意:你有N个开区间,每个区间有个重量wi,你要选择一些区间,使得满足:每个点被不超过K个区间覆盖的前提下,重量最大 思路:感觉是很好想的费用流,把每个区间首尾相连,费用为该区间的重量的相反数(由 ...

  5. openGL加载obj文件+绘制大脑表层+高亮染色

    绘制大脑表层并高亮染色的工作是以openGL加载obj文件为基础的,这里是我们用到的原始程序:只能加载一个obj文件的demo. 然而,一个完整的大脑表层是由很多分区组成的,因此我们的程序需要支持两个 ...

  6. ztree2.6给菜单增加title提示信息[转]

    自定义数据格式的情况下(isSimpleData: true) 在setting中自定义一个属性如 remark:"remark", callback中调用函数 nodeCreat ...

  7. [USACO08OPEN]牛的车Cow Cars

    题目描述 N (1 <= N <= 50,000) cows conveniently numbered 1..N are driving in separate cars along a ...

  8. 利用PHP SOAP实现WEB SERVICE[转载]

    php有两个扩展可以实现web service,一个是NuSoap,一个是php 官方的soap扩展,由于soap是官方的,所以我们这里以soap来实现web service.由于默认是没有打开soa ...

  9. Substrings--poj1226(字符串)

    Description You are given a number of case-sensitive strings of alphabetic characters, find the larg ...

  10. loj6172 Samjia和大树(树形DP+找规律)

    题目: https://loj.ac/problem/6172 分析: 首先容易得出这样的dp式子 然后发现后面那个Σ其实是两段区间,可以用总和减去中间一段区间表示,所以只要维护个前缀和就ok了 这样 ...