#高斯消元,数学期望#CF24D Broken Robot

博客分析了一道名为'Broken Robot'的问题,机器人在一个n行m列的方阵中随机移动,求从(i,j)到最后一行的期望时间。通过高斯消元方法解决该问题,讨论了不同情况下的转移方程和时间复杂度,最后优化到O(n^2)的时间复杂度。" 121860001,11684142,Flutter 2.0全平台稳定发布:Web、桌面及嵌入式设备新进展,"['移动开发', 'Flutter', 'Dart', 'Android', 'Web开发']

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目

在一个nnnmmm列的方阵中,一个机器人初始在(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,j1),(i+1,j)需要一个单位的时间,它也可以停留,问到达第nnn行的期望时间


分析

首先把初始坐标以上的部分去掉
f[i][j]f[i][j]f[i][j]表示从(i,j)(i,j)(i,j)出发到最后一行的期望时间
m=1m=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])+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]+2f[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(n1)
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][j1]+f[i+1][j])+1(j=m)41(f[i][j]+f[i][j1]+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][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)
但是这岂不是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]);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值