接触的第一道概率dp,这个题和以前做的唯一区别就是加了一个概率,但是也是参照了别人的思路做出来的。
dp[i][j]表示在第i,j格子所期望的。p[i][j][0], p[i][j][1], p[i][j][2]分别表示三种传送的概率。
dp[i][j] = p[i][j][0] * dp[i][j] + p[i][j][1] * dp[i][j + 1] + p[i][j][2] * dp[i + 1][j] + 2;
可以推出来 dp[i][j] = ( p[i][j][1] * dp[i][j - 1] + p[i][j][2] * dp[i + 1][j] + 2 ) / 1 - p[i][j][0];
这样就是倒退的过程了,要求dp[i + 1][j] 和 dp[i][j + 1] 就可以求 dp[i][j]。
/*************************************************************************
> File Name: hdoj3853.cpp
> Author: AcToy
> Mail: ycsgldy@163.com
> Created Time: 2013年07月17日 星期三 09时19分05秒
************************************************************************/
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <climits>
#include <cstdio>
#include <string>
#include <vector>
#include <queue>
#include <cmath>
#include <stack>
#include <map>
#include <set>
using namespace std;
typedef unsigned int u32;
typedef long long i64;
typedef unsigned long long u64;
typedef vector<int> IV;
typedef vector<bool> BV;
typedef pair<int,int> II;
typedef vector<II> IIV;
#define For(t,v,c) for(t::const_iterator v=c.begin(); v!=c.end(); ++v)
const int INF = 0x7FFFFFFF;
const double eps = 1E-10;
const double PI = acos(-1);
const int maxn = 1010;
double dp[maxn][maxn], p[maxn][maxn][3];
int r, c;
int main()
{
while(scanf("%d%d", &r, &c) == 2) {
for(int i = 1; i <= r; ++i)
for(int j = 1; j <= c; ++j)
for(int k = 0; k < 3; ++k)
scanf("%lf", &p[i][j][k]);
dp[r][c] = 0;
p[r][c][0] = 1;
for(int i = r; i >= 1; --i)
for(int j = c; j >= 1; --j)
for(int k = 0; k < 3; ++k) {
if(p[i][j][0] == 1) continue;
double tmp = 1 / (1 - p[i][j][0]);
dp[i][j] = (p[i][j][1] * dp[i][j + 1] + p[i][j][2] * dp[i + 1][j] + 2) * tmp;
}
printf("%.3lf\n", dp[1][1]);
}
return 0;
}