引用:https://blog.csdn.net/auto_ac/article/details/9907881
很多概率题总逃不开用dp转移。
期望题总是倒着推过来的,概率是正着推的,多做题就会理解其中的原因
有些期望题要用到有关 概率 或 期望的常见公式或思想
遇到dp转移方程(组)中有环的,多半逃不出高斯消元(手动 和 写代码 两种)
这套题中还有道树上的dp转移,还用dfs对方程迭代解方程, 真是大开眼界了
当然还有与各种算法结合的题,关键还是要学会分析
当公式或计算时有除法时, 特别要注意分母是否为零
入门题:http://acm.hdu.edu.cn/showproblem.php?pid=3853
题意:一开始在矩阵左上角,每次有三种可能的选择(有对应的概率)向下走、向右走、原地不动,每次都有2的消耗,问到矩阵右下角的期望消耗是多少?
分析:设dp[i][j]表示从位置[i,j]到右下角的期望,那么dp[i][j]=dp[i][j]*(原地不动的概率)+dp[i+1][j]*(向下走的概率)+dp[i][j+1]*(向右走的概率)移项得公式
#include<cstdio> using namespace std; const int M=1003; double p[M][M][5],dp[M][M]; int main(){ int n,m; while(~scanf("%d%d",&n,&m)){ for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) scanf("%lf%lf%lf",&p[i][j][1],&p[i][j][2],&p[i][j][3]); dp[n][m]=0; for(int i=1;i<=n;i++) dp[i][m+1]=0; for(int i=1;i<=m;i++) dp[n+1][i]=0; for(int i=n;i>0;i--){ for(int j=m;j>0;j--){ if(p[i][j][1]==1||i==n&&j==m) continue; dp[i][j]=(dp[i+1][j]*p[i][j][3]+dp[i][j+1]*p[i][j][2]+2)/(1-p[i][j][1]); } } printf("%.3f\n",dp[1][1]); } return 0; }