【codeforces 24D】Broken Robot

【原题题面】传送门

【题解大意】

设f[i][j]表示机器人从位置(i,j)走到最后一行所需移动的期望次数,逆序递推。

注意特判在第一列和第M列的情况。

(如果f[i][j]表示机器人从(x,y)走到(i,j)位置所需移动的期望次数,并且正序递推

那么最后计算答案时需要算出从(x,y)到最后一行每个位置的概率并且求其乘积的和)

f[i][j] = 1/4*(f[i+1][j]+f[i][j+1]+f[i][j-1]+f[i][j]);

又由于构成了一个只有对角线及其左右两边有数值的三角矩阵,所以高斯消元的过程可以简化在O(m)。

【code】

#include<bits/stdc++.h>
using namespace std;
//#define File ""
#define ll long long
inline void file(){
    freopen("in.in","r",stdin);
    freopen("out.out","w",stdout);
}
inline int read(){
    int x=0,f=1;   char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();}
    while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0'; ch=getchar();}
    return x*f;
}
const int mxn = 1e3+10;
int n,m,x,y;
double a[mxn][mxn],f[mxn][mxn];

inline void wor(){
    for(int i = 1;i <= m; ++i){
        double w = 1.0 / a[i][i];
        a[i][i] *= w;
        a[i][m+1] *= w;
        if(i == m) break;
        a[i][i+1] *= w;
        w = a[i+1][i] / a[i][i];
        a[i+1][i] -= w*a[i][i];
        a[i+1][i+1] -= w*a[i][i+1];
        a[i+1][m+1] -= w*a[i][m+1];
        a[i+1][m+1] -= a[i+1][i]*a[i][m+1]/a[i][i];
        a[i][m+1] -= a[i][i+1]*a[i+1][m+1]/a[i+1][i+1];
    }
    for(int i = m-1; i; i--)
        a[i][m+1] -= a[i+1][m+1]*a[i][i+1];
}
int main(){
    file();
    n = read(),m = read(),x = read(),y = read();

    for(int i = n-1;i >= x; i--){
        a[1][1] = a[m][m] = -2/3.0;
        a[1][2] = a[m][m-1] = 1/3.0;
        a[1][m+1] = -f[i+1][1]/3.0 - 1;
        a[m][m+1] = -f[i+1][m]/3.0 - 1;
          if(m == 1) a[1][1] = -1/2.0,a[m][m+1] = -f[i+1][m]/2.0 - 1;

        for(int j = 2;j < m; ++j){
            a[j][j] = -3/4.0;
            a[j][j-1] = a[j][j+1] = 1/4.0;
            a[j][m+1] = -f[i+1][j]/4.0 - 1;
        }
        wor();

        for(int j = 1;j <= m; ++j) f[i][j] = a[j][m+1];
    }
    printf("%.10f
",f[x][y]);
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/ve-2021/p/11053280.html