每行之间有递推关系,一行之内有环形关系的转移
高斯消元解方程即可
直接进行高斯消元会超时
但是这个矩阵具有奇妙的性质:只有对角线和两侧有数
消元的次数非常少
单次操作可以看成是线性的
#include<bits/stdc++.h>
using namespace std;
#define rep(i,j,k) for(int i = j;i <= k;++i)
#define repp(i,j,k) for(int i = j;i >= k;--i)
int n , m;
int st,en;
double f[1001][1001];
double a[1001][1001],b[1001];
void gus(int x)
{
rep(i,1,m-1)
{
int j = i + 1;
{
double det = a[j][i] / a[i][i];
rep(k,i,i+1) a[j][k] -= a[i][k] * det;
b[j] -= b[i] * det;
}
}
f[x][m] = b[m] / a[m][m];
repp(i,m-1,1) f[x][i] = (b[i] - a[i][i+1]*f[x][i+1]) / a[i][i];
}
int main()
{
freopen("in.in","r",stdin);
freopen("out.out","w",stdout);
scanf("%d%d%d%d",&n,&m,&st,&en);
rep(i,1,m) f[n][i] = 0.0;
repp(x,n-1,st)
{
if(m == 1)
{
a[1][1] = -1.0/2.0;
b[1] = -1.0*f[x+1][1]/2-1.0;
}
else
{
a[1][1] = -2.0/3.0;a[1][2] = 1.0/3.0;
b[1] = -1.0*f[x+1][1]/3-1.0;
}
rep(i,2,m-1)
{
a[i][i-1] = a[i][i+1] =1.0/4;a[i][i] = -3.0/4.0;
b[i] = -1.0*f[x+1][i]/4-1.0;
}
if(m > 1)
{
a[m][m-1] = 1.0/3.0;a[m][m] = -2.0/3.0;
b[m] = -1.0*f[x+1][m]/3-1.0;
}
gus(x);
}
printf("%.8lf",f[st][en]);
return 0;
}