CF24D Broken robot题解
CF24D\(\mathbf{} \begin{Bmatrix} \frac{{\Large CF24D} }{{\color{Red}\Large Solution} }\mathbf{} {No.29} \end{Bmatrix}\times{}\) NeeDna
题目描述
有一个 \(n\) 行 \(m\) 列的矩阵,现在有一个机器人在 \((x,y)\),它每一步等概率向左,右,下走或原地不动,但不能走出矩阵,问走到最后一行期望的步数。
注意,\((1,1)\) 是木板的左上角,\((n,m)\) 是木板的右下角。
题解
先排除 \(2\) 个特殊情况,\(m=1\) 或 \(n=x\),两个的答案分别是 \(2\times (n-x)\),\(0\)。
我们想一下暴力,设 \(f_{i,j}\) 为 \((x,y)\) 出发,到达最后一行的期望步数。那么答案就是 \(f_{x,y}\) 。
思考 \(f_{i,j}\) 怎么求,这个是简单的,从自己之后会到达的点回推即可,我么可以列出来以下式子:
\[\left\{\begin{matrix}f_{i,1}=\dfrac{1}{3}\cdot(f_{i+1,1}+f_{i,2}+f_{i,1})+1\\f_{i,j}=\dfrac{1}{4}\cdot(f_{i,j}+f_{i,j-1}+f_{i,j+1}+f_{i+1,j})+1\\f_{i,m}=\dfrac{1}{3}\cdot(f_{i,m}+f_{i,m-1}+f_{i+1,m})+1\end{matrix}\right.
\]
这个是有后效性的,我们可以高斯消元 \(\Theta(n^6)\) 啥也过不了。
发现每一行的转移只和下一行和本行有关所以可以每一行分别高斯消元 \(\Theta(n^4)\)。
接下来我们把矩阵拿出来看一下
\[\begin{bmatrix} 2 & -1 &0&0&0&0&0&0&0&0&0\\ -1 & 3&-1&0&0&0&0&0&0&0&0\\ 0&-1 & 3&-1&0&0&0&0&0&0&0\\ 0&0&-1 & 3&-1&0&0&0&0&0&0\\ 0&0&0&-1 & 3&-1&0&0&0&0&0\\0&0&0&0& -1 & 3&-1&0&0&0&0\\ 0&0&0&0&0&-1 & 3&-1&0&0&0\\ 0&0&0&0&0&0&-1 & 3&-1&0&0\\ 0&0&0&0&0&0&0&-1 & 3&-1&0\\ 0&0&0&0&0&0&0&0&-1 &3&-1\\ 0&0&0&0&0&0&0&0&0&-1&2\end{bmatrix}
\quad\]
发现了吧?这是个稀疏图哈~
所以我们可以直接把方程解出来,改的项很少,每一个元删除一项就好了,应为最后一个元只有两个有,消掉一个就只剩 \(1\) 个了,我们剩下的每组方程都只有 \(2\) 项了,用上一项得出来的数减掉就得到了,所以暴力求也不是很难。 \(\Theta(n^2)\)。
code:
#include<bits/stdc++.h>
using namespace std;
const int N=1e3+10;
int n,m,x,y;
double f[N],a[N][N],b[N];
void build(){
	a[m][m]=a[1][1]=(double)-2/3; a[m][m-1]=a[1][2]=(double)1/3;
    b[1]=(double)-f[1]/3-1; b[m]=(double)-f[m]/3-1;
    for (int i=2;i<m;i++){
        a[i][i-1]=a[i][i+1]=(double)1/4;
        a[i][i]=(double)-3/4;
        b[i]=(double)-f[i]/4-1;
    }
}
void gauss(){
	for(int i=1;i<m;i++){
		double rate=a[i+1][i]/a[i][i];
        a[i+1][i]-=rate*a[i][i];
        a[i+1][i+1]-=rate*a[i][i+1];
        b[i+1]-=rate*b[i];
	}f[m]=b[m]/a[m][m];	
	for(int i=m-1;i>0;i--){
        f[i]=(b[i]-f[i+1]*a[i][i+1])/a[i][i];
    }
}
int main(){
    cin>>n>>m>>x>>y;
    if(x==n){cout<<fixed<<setprecision(8)<<0;return 0;}
    if(m==1){cout<<fixed<<setprecision(8)<<2*(n-1);return 0;}
    for(int i=n;i>x;i--){
    	build();gauss();
	}cout<<fixed<<setprecision(8)<<f[y];
    return 0;
}

                
            
        
浙公网安备 33010602011771号