注意:在概率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. Linux(4):文件属性

    文件属性: # 重点: 磁盘空间不足 和 软链接与硬链接的区别 查看文件的属性: # ls lhi 文件 [root@NEO ~]# ls -lhi /etc/hosts 130078 -rw-r-- ...

  2. html5的新通讯技术socket.io,实现一个聊天室

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  3. Codeforces917C. Pollywog

    $n \leq 1e8$个石头,$x \leq 8$个蝌蚪一开始在最左边$x$个石子,要跳到最右的$x$个,每次只能最左边的蝌蚪跳一次,一个石头不能站两个蝌蚪,跳可以跳$1到k,x \leq k \l ...

  4. jQuery的切换函数(hover,toggle)

    1.hover:(鼠标悬停与离开事件) 一个模仿悬停事件(鼠标移动到一个对象上面及移出这个对象)的方法.这是一个自定义的方法,它为频繁使用的任务提供了一种“保持在其中”的状态. 当鼠标移动到一个匹配的 ...

  5. Kibana 可视化监控报警插件 KAAE 的介绍与使用

    https://blog.csdn.net/phachon/article/details/53424631 https://blog.csdn.net/Dragon714/article/detai ...

  6. HDU 4738 割边

    Caocao's Bridges Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  7. POJ 3461 字符串出现次数 && HDU1711 字符串第一次出现的位置 模板题

      Oulipo Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 48387   Accepted: 19261 Descri ...

  8. HDU 5665 Lucky

    看有没有0和1,都有的时候是YES,否则是NO #include<cstdio> #include<cstring> #include<cmath> #includ ...

  9. File类的三种构造方法

    package cn.zmh.File; import java.io.File; /* * * File类的构造方法 三种重载形式 * * */ public class FileDemo1 { p ...

  10. 【转载】Unix设计哲学 & 回车换行八卦 & EOF八卦 & UNIX目录结构八卦

    昨天看了这篇文章 <关于Unix哲学> 首先用了两个例子,用风扇吹出空肥皂盒 和 太空铅笔,来说明简单设计也能派上作用吧. Unix哲学,Wikipedia上列出了好几个版本,不同的人有不 ...