坏掉的机器人
从(x,y)到第n行的行动次数期望值 每次可以等概率的留在原地 向左移动 向右移动和向下移动
在倒推的时候 概率已经被包括在已经计算出来的答案中了 就可以直接利用期望的性质计算 而不需要概率数组
高斯消元的时候,把阶段内相互制约的部分作为消元的对象
这道题由于矩阵中有很多的0 采用普通的高斯消元会浪费时间,所以应当采用特殊的消元方法
先消成每行只有两个元素的矩阵 然后再倒推解决
并不是简单的根据当前行把上下两行给消去就可以 因为还会影响到其他的系数
把初等行变换优化成O(1)
#include <iostream>
#include <cstdio>
#include <cstring>
const int N=1010;
using namespace std;
int read()
{
int x=0,f=0,c=getchar();
while(c<'0'||c>'9'){if(c=='-')f=1;c=getchar();}
while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
return f?-x:x;
}
double a[N][N],f[N][N],b[N];
int n,m,x,y;
void SWAP(int i,int j){for(int k=1;k<=m;k++) swap(a[i][k],a[j][k]); swap(b[i],b[j]);}
void MUL(int i,int j,double r)
{
for(int k=j;k<=j+1;k++)a[i][k]-=r*a[j][k]; b[i]-=r*b[j];
}
int main()
{
n=read(); m=read(); x=read(); y=read();
if(m==1){ printf("%.4lf",(n-x)*2.0);return 0;}
for(int p=n-1;p>=x;p--)
{
a[1][1]=2.0/3; a[1][2]=-1.0/3; b[1]=1+f[p+1][1]/3;
a[m][m]=2.0/3; a[m][m-1]=-1.0/3; b[m]=1+f[p+1][m]/3;
for(int j=2;j<=m-1;j++)//一共有m个方程
a[j][j]=3.0/4,a[j][j+1]=a[j][j-1]=-1.0/4,b[j]=1+f[p+1][j]/4;
for(int i=1;i<m;i++)
MUL(i+1,i,a[i+1][i]/a[i][i]);
for(int i=m;i>=1;i--)
f[p][i]=(b[i]-a[i][i+1]*f[p][i+1])/a[i][i];
}
printf("%.4lf",f[x][y]);
return 0;
}
注意需要考虑边界的特判情况

浙公网安备 33010602011771号