注意:在概率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. [POJ1984]Navigation Nightmare

    [POJ1984]Navigation Nightmare 试题描述 Farmer John's pastoral neighborhood has N farms (2 <= N <= ...

  2. 【python可视化系列】python数据可视化利器--pyecharts

    学可视化就跟学弹吉他一样,刚开始你会觉得自己弹出来的是噪音,也就有了在使用python可视化的时候,总说,我擦,为啥别人画的图那么溜: [python可视化系列]python数据可视化利器--pyec ...

  3. [NOIP1999] 提高组 洛谷P1016 旅行家的预算

    题目描述 一个旅行家想驾驶汽车以最少的费用从一个城市到另一个城市(假设出发时油箱是空的).给定两个城市之间的距离D1.汽车油箱的容量C(以升为单位).每升汽油能行驶的距离D2.出发点每升汽油价格P和沿 ...

  4. 1597: [Usaco2008 Mar]土地购买 [ dp+斜率优化 ] 未完

    传送门 1597: [Usaco2008 Mar]土地购买 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1979  Solved: 705[Subm ...

  5. msp430项目编程21

    msp430中项目---直流电机控制系统 1.定时器工作原理 2.电路原理说明 3.代码(显示部分) 4.代码(功能实现) 5.项目总结 msp430项目编程 msp430入门学习

  6. 2017-10-04-morning

    改题面只有1改为0 .. #include <cstring> #include <cstdio> inline void read(int &x) { x=; reg ...

  7. Best Time to Buy and Sell Stock(动态规划)

    Say you have an array for which the ith element is the price of a given stock on day i. If you were ...

  8. java基础语法——方法,static关键字

    一:方法: 1.什么是方法: 通俗地讲,方法就是行为.它是完成特定功能的代码块能执行一个功能.它包含于类和对象中. 2.为什么要有方法: *提高代码的复用性. *提高效率 *利于程序维护 3.命名规则 ...

  9. Spring Boot使用MyBatis 3打印SQL的配置

    普通Spring下的XML文件配置: <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE co ...

  10. kvm虚拟化学习笔记(一)之kvm虚拟化环境安装

    平时一直玩RHEL/CentOS/OEL系列的操作,玩虚拟化也是采这一类系统,kvm在RHEL6系列操作系统支持比较好,本文采用采用OEL6.3操作系统,网上所有文章都说KVM比xen简单,我怎么感觉 ...