题意:给定 R*C 的网格,每个网格都有 p1的几率留在原地 ,p2 的几率往右走 ,p3 的几率往下走,每次操作消耗 2 魔力,求从
(1,1) 走到 (R,C)的期望魔力消耗值
分析:设 dp[ r ][ c ]表示 从 ( r , c ) 走到 ( R , C )的 期望魔耗 ,则 dp[ R ][ C ] = 0;
转移方程 dp[ r ][ c ] = 2 + dp[ r ][ c ] * p[ r ][ c ][ 0 ] //留在原地
+ dp[ r ][ c+1 ] * p[ r ][ c ][ 1 ] //向右走
+ dp[ r+1 ][ c ] * p[ r ][ c ][ 2 ] //向下走
移项: dp[ r ][ c ] = (2 + dp[ r ][ c+1 ] * p[ r ][ c ][ 1 ] + dp[ r+1 ][ c ] * p[ r ][ c ][ 2 ])/ (1 - p[ r ][ c ][ 0 ])
代码:
#include<cstdio>
#include<iostream>
using namespace std;
const int N = 1005 ;
double p[N][N][3];
double dp[N][N];
int R,C;
int main()
{
while(~scanf("%d%d",&R,&C))
{
for(int r=1;r<=R;r++)
for(int c=1;c<=C;c++)
for(int i=0;i<3;i++)
scanf("%lf",&p[r][c][i]);
dp[R][C]=0.0;
for(int r=R;r>=1;r--)
for(int c=C;c>=1;c--)
{
if(R==r&&c==C) continue;
if(p[r][c][0]==1.0) continue;
dp[r][c]=(dp[r][c+1]*p[r][c][1]+dp[r+1][c]*p[r][c][2]+2)/(1-p[r][c][0]);
}
printf("%.3f\n",dp[1][1]);
}
return 0;
}