HDU 3853 LOOPS(概率dp)

題解:

由題可以得:(x,y)到(x,y+1)的概率是 p[x][y][1],到(x+1,y)的概率是 p[x][y][2],不動的概率是 p[x][y][0]。所以可以推出下面的公式:dp[i][j] = dp[i][j+1]*p[i][j][1] + dp[i+1][j]*p[i][j][2] + dp[i][j]*p[i][j][0] + 2。

即:dp[i][j] = (dp[i][j+1]*p[i][j][1] + dp[i+1][j]*p[i][j][2]+2) / (1 - p[i][j][0])。

#include <algorithm>
#include  <iostream>
#include   <cstdlib>
#include   <cstring>
#include    <cstdio>
#include    <string>
#include    <vector>
#include    <bitset>
#include     <stack>
#include     <cmath>
#include     <deque>
#include     <queue>
#include      <list>
#include       <set>
#include       <map>
#pragma comment(linker, "/STACK:1024000000,1024000000")
#define line printf("---------------------------\n")
#define mem(a, b) memset(a, b, sizeof(a))
#define pi acos(-1)
using namespace std;
typedef long long ll;
const double eps = 1e-9;
const int inf = 0x3f3f3f3f;
const int mod = 1e9+7;
const int maxn = 1000+10;

double p[maxn][maxn][3], dp[maxn][maxn];

int main(){
	int n, m;
	while(~scanf("%d %d", &n, &m)){
		for(int i = 1; i <= n; i++){
			for(int j = 1; j <= m; j++){
				scanf("%lf %lf %lf", &p[i][j][0], &p[i][j][1], &p[i][j][2]);
			}
		}
		dp[n][m] = 0;
		for(int i = n; i > 0; i--){
			for(int j = m; j > 0; j--){
				if((i == n && j == m) || p[i][j][0] == 1.00){
					continue;
				}
				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]);
			}
		}
		printf("%.3lf\n", dp[1][1]);
	}
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章