#高斯消元,數學期望#CF24D Broken Robot

題目

在一個nnmm列的方陣中,一個機器人初始在(i,j)(i,j),它隨機往(i,j+1),(i,j1),(i+1,j)(i,j+1),(i,j-1),(i+1,j)需要一個單位的時間,它也可以停留,問到達第nn行的期望時間


分析

首先把初始座標以上的部分去掉
f[i][j]f[i][j]表示從(i,j)(i,j)出發到最後一行的期望時間
m=1m=1f[i][1]=12(f[i][1]+f[i+1][1])+1f[i][1]=\frac{1}{2}(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][j]=f[i+1][j]+2==2(n1)f[i][j]=f[i+1][j]+2=\cdots=2*(n-1)
m>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][j1]+f[i+1][j])+1(j=m)14(f[i][j]+f[i][j1]+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}
然而它是有後效性的,不可做,考慮高斯消元
於是得到三個方程
{2f[i][j]f[i][j+1]f[i+1][j]=3(j=1)2f[i][j]f[i][j1]f[i+1][j]=3(j=m)3f[i][j]f[i][j+1]f[i][j1]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}
但是這豈不是O(n6)O(n^6),考慮把下一行當做常量,那麼時間複雜度O(n4)O(n^4)

但是如果畫出這個矩陣,就可以知道這個矩陣比較稀疏,而且只需要維護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),實在是噁心至極


代碼

#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]);
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章