坏掉的机器人

给定一张 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;
}
发布了329 篇原创文章 · 获赞 28 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_45323960/article/details/104788413