题意:
在一块r*c的棋盘上,从位置(1,1)的地方走到位置为(r,c)的地方,每走一步的代价为2,在位置(i,j)可能会走到位置(i+1,j),(i,j+1)以及(i,j),题目中给出每个点走向下一个方向的概率,求花的总代价。
分析:
一道很基础的概率dp,dp[i][j]表示的是从位置(i,j)走到(r,c)所花的代价,那么dp[r][c] = 0 , 最后要求的就是dp[1][1]。
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <algorithm>
#include <queue>
#include <stack>
#include <map>
using namespace std ;
#define mem(a) memset(a,0,sizeof(a))
#define inf 100000005
int const maxn = 1005;
double dp[maxn][maxn];
//dp[i][j]表示的是从位置(i,j)走到位置(n,c)需要的代价,答案是dp[1][1]
struct node
{
double now;
double y_1;
double x_1;
}A[maxn][maxn];
int main()
{
int r,c;
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",&A[i][j].now,&A[i][j].y_1,&A[i][j].x_1);
}
}
mem(dp);
dp[r][c] = 0 ;
for(int i = r ; i > 0 ; i--)
{
for(int j = c ; j > 0 ; j--)
{
if(i==r&&j==c)continue;
if(A[i][j].now==1)continue; //这里就是这个题目的陷阱,因为假如在一个点在原地踏步的概率是1的话,那么
//走进来就出不去了
dp[i][j] = (dp[i+1][j]*A[i][j].x_1 + dp[i][j+1]*A[i][j].y_1 + 2)/(1-A[i][j].now) ;
}
}
printf("%.3lf\n",dp[1][1]);
}
return 0 ;
}