【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\n",f[x][y]); return 0; }
G102的孤儿们都要好好的啊。