给定一张 N*M 的棋盘,有一个机器人处于(x,y)位置。
这个机器人可以进行很多轮行动,每次等概论地随机选择停在原地、向左移动一格、向右移动一格或向下移动一格。
当然机器人不能移出棋盘。
求机器人从起点走到最后一行的任意一个位置上,所需行动次数的数学期望值。
输入格式
第一行包含两个整数 N 和 M。
第二行包含两个整数 x 和 y,表示机器人的初始位置。
设定棋盘左上角为(1,1),右下角为(N,M)。
输出格式
输出一个实数,表示数学期望,结果保留四位小数。
数据范围
1≤N,M≤1000
输入样例:
10 14
5 14
输出样例:
18.0038
#include<bits/stdc++.h>
using namespace std;
const int N = 1e3 + 10;
int n, m, x, y;
double f[N][N], a[N][N];
inline void gauss() {
for (int i = 1; i <= m - 1; i++) {
double r = a[i][i];
a[i][i] /= r, a[i][i + 1] /= r, a[i][m + 1] /= r;
double t = a[i + 1][i];
a[i + 1][i] = 0;
a[i + 1][i + 1] -= a[i][i + 1] * t;
a[i + 1][m + 1] -= a[i][m + 1] * t;
}
a[m][m + 1] /= a[m][m], a[m][m] = 1;
for (int i = m; i >= 2; i--)
a[i - 1][m + 1] -= a[i][m + 1] * a[i - 1][i], a[i - 1][i] = 0;
}
int main() {
scanf("%d%d%d%d", &n, &m, &x, &y);
if (m == 1) printf("%.4lf", 2.0 * (n - x));
else {
for (int i = n - 1; i >= x; i--) {
a[1][1] = a[m][m] = 2.0 / 3;
a[1][2] = a[m][m - 1] = -1.0 / 3;
a[1][m + 1] = 1 + f[i + 1][1] / 3;
a[m][m + 1] = 1 + f[i + 1][m] / 3;
for (int j = 2; j <= m - 1; j++) {
a[j][j - 1] = a[j][j + 1] = -1.0 / 4;
a[j][j] = 3.0 / 4;
a[j][m + 1] = 1 + f[i + 1][j] / 4;
}
gauss();
for (int j = 1; j <= m; j++)
f[i][j] = a[j][m + 1];
}
printf("%.4lf", f[x][y]);
}
return 0;
}