HDU 3853 LOOPS(期望DP)(第一篇期望dp)

来源:互联网 发布:火汉字笔顺演示软件 编辑:程序博客网 时间:2024/05/14 07:19

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

一:题意:

说一个叫Homura的人被困在了一个迷宫里,该迷宫是一个矩行, 矩阵的大小为R*C。

刚开始Homura 在(1,1)位置,迷宫的出口在(R,C),对于Homura 当他在每一个格子中

都可以费 2 个魔法值开启传送通道,该通道可以通向三个方向,原地,向右走一格,向下走一格。

要求你求出他到出口需要花费的魔法值的期望是多少。

二:数学期望的求法。

1,数学期望公式:

对于离散型随机变量 X,其概率为P,则有:



这两个公式在解期望题中非常有用,第一个是告诉你怎么计算数学期望,第二个是转化公式我们可以利用

该公式将我们要求的期望不断转化成其他小的容易求解的问题的线性组合。

有了这两个公式我们在求解的时候我们还需注意:要明确离散型随机变量X是什么。

在这个问题中X为花费的魔法值,而且Homura每次花费的魔法值为2 即:Xi = 2(i=1,2,,,n)。

明白这一点很关键。

在该题我还用到公式:


2,令:dp[i][j] //记录改点到出口的数学期望 start[x][y],right[x][y],low[x][y],分别表示(x,y)

到原点,往右,往下的概率,所以有递推公式:

dp[x][y]=dp[x][y] * start[x][y] + (right[x][y] * dp[x][y+1] + low[x][y] * dp[x+1][y] + 2);

dp[x][y]=(right[x][y] * dp[x][y+1] + low[x][y] * dp[x+1][y] + 2) / (1-start[x][y]);

但要注意分母不能为0,由该公式可知当 1 = start[x][y] 时right[x][y] = low[x][y] = 0;

所以这是将dp[x][y] = 0;  终点的数学期望为 0;

最后给一个数学期望求解的网址:http://kicd.blog.163.com/blog/static/126961911200910168335852/


三,代码:

#include <iostream>#include <stdio.h>#include <string.h>#include <stdlib.h>#include <math.h>using namespace std;const int Max=1005;struct node{    double start;    double low;    double right;};node mat[Max][Max];double dp[Max][Max];int R,C;double DFS(int x,int y){    if(dp[x][y]!=-1)        return dp[x][y];    double res=0;    if(x<=R&&y<=C)    {        if(fabs(1-mat[x][y].start)<1e-6)            return dp[x][y]=0;//浮点数误差处理        //分母为0;        res+=mat[x][y].right*DFS(x,y+1);        res+=mat[x][y].low*DFS(x+1,y);        res=(2+res)/(1-mat[x][y].start);    }    return dp[x][y]=res;}int main(){    while(scanf("%d%d",&R,&C)!=EOF)    {        for(int i=1; i<=R; i++)            for(int j=1; j<=C; j++)                scanf("%lf%lf%lf",&mat[i][j].start,&mat[i][j].right,&mat[i][j].low);        for(int i=1;i<=R;i++)            for(int j=1;j<=C;j++)              dp[i][j]=-1;        dp[R][C]=0;//终点        DFS(1,1);        printf("%.3f\n",dp[1][1]);    }    return 0;}




0 0
原创粉丝点击