HDOJ 3853 LOOPS(DP期望入门)

题意:r*c 的方格地图,起点在 (1,1),终点在(r , c),方向只有三种:呆在原地,向右走,向下走,每走一步花费为 2 。
给出每个点三种方向走的概率,求出从起点到终点走的期望花费。
既然求期望,那么就倒着走。
设dp[i][j]是当在(i , j)点时,到达终点的期望步数,因为期望的线性关系,期望可以由若干个子期望求出,那么对于(i,j) 点的三种方向,下一步可能走到点为:   (i,j),(i,j+1),(i+1,j);
假设概率分别为p[1],p[2],p[3];
那么由期望公式可得:
dp[i][j]=p[1]*dp[i][j]+p[2]*dp[i][j+1]+p[3]*dp[i+1][j]+2;
化简可得:
dp[i][j]=(p[2]*dp[i][j+1]+p[3]*dp[i+1][j]+2)/(1-p[1]);
转移就完成了。
再来考虑边界: dp[r][c]=0;

求期望感觉难在对状态的转移,要将这个点所有的下一步的状态都考虑好,然后乘以其概率,再累加子期望*子概率。那么得出来的就是父期望,公式也就是:E(aX+bY)=a*E(X)+b*E(Y).

ps:数学不好是硬伤。

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
int r,c;
double dp[1005][1005],p[1005][1005][4];
int main()
{
    while(scanf("%d%d",&r,&c)!=EOF)
    {
        for(int i=1;i<=r;i++)
        {
            for(int j=1;j<=c;j++)
            {
                for(int k=1;k<=3;k++)
                    scanf("%lf",&p[i][j][k]);
            }
        }
        dp[r][c]=0;
        for(int i=r;i>=1;i--)
        {
            for(int j=c;j>=1;j--)
            {
                if(i==r&&j==c||p[i][j][1]==1)
                    continue;
                dp[i][j]=(p[i][j][2]*dp[i][j+1]+p[i][j][3]*dp[i+1][j]+2)/(1.0-p[i][j][1]);
            }
        }
        printf("%.3f\n",dp[1][1]);
    }
return 0;
}

你可能感兴趣的:(梁晨)