题目
在一个nnn行mmm列的方阵中,一个机器人初始在(i,j)(i,j)(i,j),它随机往(i,j+1),(i,j−1),(i+1,j)(i,j+1),(i,j-1),(i+1,j)(i,j+1),(i,j−1),(i+1,j)需要一个单位的时间,它也可以停留,问到达第nnn行的期望时间
分析
首先把初始坐标以上的部分去掉
设f[i][j]f[i][j]f[i][j]表示从(i,j)(i,j)(i,j)出发到最后一行的期望时间
若m=1m=1m=1,f[i][1]=12(f[i][1]+f[i+1][1])+1f[i][1]=\frac{1}{2}(f[i][1]+f[i+1][1])+1f[i][1]=21(f[i][1]+f[i+1][1])+1
∴f[i][1]=f[i+1][1]+2\therefore f[i][1]=f[i+1][1]+2∴f[i][1]=f[i+1][1]+2
那么f[i][j]=f[i+1][j]+2=⋯=2∗(n−1)f[i][j]=f[i+1][j]+2=\cdots=2*(n-1)f[i][j]=f[i+1][j]+2=⋯=2∗(n−1)
若m>1m>1m>1,f[i][j]={13(f[i][j]+f[i][j+1]+f[i+1][j])+1(j=1)13(f[i][j]+f[i][j−1]+f[i+1][j])+1(j=m)14(f[i][j]+f[i][j−1]+f[i][j+1]+f[i+1][j])+1(1<j<m)f[i][j]=\begin{cases}\frac{1}{3}(f[i][j]+f[i][j+1]+f[i+1][j])+1(j=1)\\\frac{1}{3}(f[i][j]+f[i][j-1]+f[i+1][j])+1(j=m)\\\frac{1}{4}(f[i][j]+f[i][j-1]+f[i][j+1]+f[i+1][j])+1(1<j<m)\end{cases}f[i][j]=⎩⎪⎨⎪⎧31(f[i][j]+f[i][j+1]+f[i+1][j])+1(j=1)31(f[i][j]+f[i][j−1]+f[i+1][j])+1(j=m)41(f[i][j]+f[i][j−1]+f[i][j+1]+f[i+1][j])+1(1<j<m)
然而它是有后效性的,不可做,考虑高斯消元
于是得到三个方程
{2f[i][j]−f[i][j+1]−f[i+1][j]=3(j=1)2f[i][j]−f[i][j−1]−f[i+1][j]=3(j=m)3f[i][j]−f[i][j+1]−f[i][j−1]−f[i+1][j]=4(1<j<m)\begin{cases}2f[i][j]-f[i][j+1]-f[i+1][j]=3(j=1)\\2f[i][j]-f[i][j-1]-f[i+1][j]=3(j=m)\\3f[i][j]-f[i][j+1]-f[i][j-1]-f[i+1][j]=4(1<j<m)\end{cases}⎩⎪⎨⎪⎧2f[i][j]−f[i][j+1]−f[i+1][j]=3(j=1)2f[i][j]−f[i][j−1]−f[i+1][j]=3(j=m)3f[i][j]−f[i][j+1]−f[i][j−1]−f[i+1][j]=4(1<j<m)
但是这岂不是O(n6)O(n^6)O(n6),考虑把下一行当做常量,那么时间复杂度O(n4)O(n^4)O(n4)
但是如果画出这个矩阵,就可以知道这个矩阵比较稀疏,而且只需要维护T[i][i],T[i][i+1],T[i][m+1]T[i][i],T[i][i+1],T[i][m+1]T[i][i],T[i][i+1],T[i][m+1],时间复杂度优化到O(n2)O(n^2)O(n2),实在是恶心至极
代码
#include <cstdio>
#include <cctype>
#define rr register
using namespace std;
double a[1011][1011],f[1011]; int n,m,x,y;
inline signed iut(){
rr int ans=0; rr char c=getchar();
while (!isdigit(c)) c=getchar();
while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
return ans;
}
inline void gauss(int n){
for (rr int i=1;i<=n;++i){
if (i<n) a[i][i+1]/=a[i][i];
a[i][n+1]/=a[i][i],a[i][i]=1;
a[i+1][i+1]-=a[i][i+1]*a[i+1][i];
a[i+1][n+1]-=a[i][n+1]*a[i+1][i]; a[i+1][i]=0;
}
for (rr int i=n-1;i;--i) a[i][n+1]-=a[i][i+1]*a[i+1][n+1];
}
signed main(){
n=iut(); m=iut(); n-=iut()-1,x=1,y=iut();
if (m==1) return !printf("%.10lf",(n-1)*2.0);
for (rr int j=1;j<n;++j){
a[1][1]=2,a[1][2]=-1,a[1][m+1]=f[1]+3;
a[m][m]=2,a[m][m-1]=-1,a[m][m+1]=f[m]+3;
for (rr int i=2;i<m;++i) a[i][i-1]=a[i][i+1]=-1;
for (rr int i=2;i<m;++i) a[i][i]=3,a[i][m+1]=f[i]+4;
gauss(m); for (rr int i=1;i<=m;++i) f[i]=a[i][m+1];
}
return !printf("%.10lf",f[y]);
}