• Codeforces.24D.Broken robot(期望DP 高斯消元)


    题目链接


    可能这儿的会更易懂一些(表示不想再多写了)。

    (f[i][j])表示从((i,j))到达最后一行的期望步数。那么有(f[n][j]=0)
    (m=1),答案是(2(n-x))
    否则,显然有$$f[i][1]=frac13(f[i+1][1]+f[i][1]+f[i][2])+1f[i][j]=frac14(f[i+1][j]+f[i][j]+f[i][j-1]+f[i][j+1])+1, 1<j<mf[i][m]=frac13(f[i+1][m]+f[i][m]+f[i][m-1])+1$$

    别忘了+1→_→
    写成矩阵的形式,$$2f[i][1]-f[i][2]=f[i+1][1]+3-f[i][j-1]+3f[i][j]-f[i][j+1]=f[i+1][j]+4-f[i][m-1]+2f[i][m]=f[i+1][m]+3$$

    然后就可以一行一行高斯消元了。
    注意到矩阵是个三对角矩阵,我们可以(O(n))完成消元。
    具体就是用第(i)行的两个变量消掉第(i+1)行的第(i)个变量,最后到第(m)行可以直接算出(f[i][m]),代回去。
    第一行有(2f[1]-f[2]=g[1]),消掉第二行的(f[1])变成(2.5f[2]-f[3]=g[2]+0.5g[1]),系数改成(2)(2f[2]-0.8f[3]=0.8(g[2]+0.5g[1])),重复(m-2)次即可。最后会得到(m-1)(2f[i]+a_if[i+1]=b_i),用第(m)行求出(f[m]),迭代回去。


    //62ms	7700KB
    #include <cstdio>
    #include <algorithm>
    typedef long long LL;
    const int N=1005;
    
    double A[N],B[N],f[N][N];
    
    int main()
    {
    	int n,m,x,y; scanf("%d%d%d%d",&n,&m,&x,&y);
    	if(m==1) return printf("%.5f
    ",2.0*(n-x)),0;
    	for(int i=n-1; i>=x; --i)
    	{
    		A[1]=-1, B[1]=f[i+1][1]+3;
    		for(int j=2; j<m; ++j)
    		{
    			A[j]=-1, B[j]=4+f[i+1][j]+0.5*B[j-1];
    			double t=2/(3+0.5*A[j-1]); A[j]*=t, B[j]*=t;
    		}
    		B[m]=f[i+1][m]+3+0.5*B[m-1], f[i][m]=B[m]/(2+0.5*A[m-1]);
    		for(int j=m-1; j; --j) f[i][j]=(B[j]-f[i][j+1]*A[j])*0.5;
    	}
    	printf("%.5f
    ",f[x][y]);
    
    	return 0;
    }
    
  • 相关阅读:
    Visual Studio 2017 Bugs
    【翻译】7种流行的单元测试命名约定
    Markdown语法
    How to build mscorlib.dll with visual studio
    Debugging
    [HDU 1020] Encoding
    [HDU 1008] Elevator
    Python学习笔记七-错误和异常
    Python学习笔记六--文件和输入输出
    Python学习笔记五--条件和循环
  • 原文地址:https://www.cnblogs.com/SovietPower/p/10542754.html
Copyright © 2020-2023  润新知