zoukankan      html  css  js  c++  java
  • codeforces 24d Broken robot 期望+高斯消元

    题目传送门

    题意:在n*m的网格上,有一个机器人从(x,y)出发,每次等概率的向右、向左、向下走一步或者留在原地,在最左边时不能向右走,最右边时不能像左走。问走到最后一行的期望。

    思路:显然倒着算期望。

      我们考虑既不是最后一行,也不靠边的一般方格,设$f[i][j]$为(i,j)这个格子的期望步数,显然有

      $f[i][j]=frac{1}{4}*(f[i][j-1]+f[i][j+1]+f[i+1][j]+f[i][j])+1$

      移项有:$f[i][j]=frac{1}{3}(f[i][j-1]+f[i][j+1]+f[i+1][j])+frac{4}{3}$。

      在我们处理处第i+1行所有的情况时,对于第i行,我们能得到像上述一样m个方程m个未知数,所以可以用高斯消元来解。

      但是朴素的高斯消元是$n^3$的,显然会T,但是我们考虑此题的所有方程,写成行列式,会发现这个行列式只有对角线,和与对角线相邻的两行是有值的,这样按初中数学知识,就可以用$O(m)$的解除方程的解。

      注意特别m=1的情况即可。

    #pragma GCC optimize (2)
    #pragma G++ optimize (2)
    #pragma comment(linker, "/STACK:102400000,102400000")
    #include<bits/stdc++.h>
    #define rep(i,a,b) for(int i=a;i<=b;i++)
    #define dep(i,b,a) for(int i=b;i>=a;i--)
    #define clr(a,b) memset(a,b,sizeof(a))
    #define pb push_back
    #define pii pair<int,int >
    using namespace std;
    typedef long long ll;
    ll rd()
    {
        ll x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    const int maxn=1010;
    double a[maxn][maxn],f[maxn][maxn],x[maxn];
    int n,m,xx,yy;
    void gauss(int id){
        for(int i=1;i<=m;i++){
            double tmp=1/a[i][i];
            a[i][i]*=tmp;
            x[i]*=tmp;
            if(i==m)break;
            a[i][i+1]*=tmp;
            a[i+1][i+1]-=a[i][i+1]*a[i+1][i];
            x[i+1]-=x[i]*a[i+1][i];
            a[i+1][i]=0;
        }
        f[id][m]=x[m];
        for(int j=m-1;j>0;j--){
            x[j]-=a[j][j+1]*x[j+1];
            f[id][j]=x[j];
        }
    }
    int main(){
        cin>>n>>m>>xx>>yy;
        if(m==1){
            printf("%d
    ",(n-xx)*2);
            return 0;
        }
        for(int i=n-1;i>=xx;i--){
            a[1][1]=1,a[1][2]=-0.5,x[1]=1.5+f[i+1][1]/2;
            a[m][m]=1,a[m][m-1]=-0.5,x[m]=1.5+f[i+1][m]/2;
            for(int j=2;j<m;j++){
                a[j][j]=1;
                a[j][j-1]=-1.0/3;
                a[j][j+1]=-1.0/3;
                x[j]=f[i+1][j]/3+4.0/3;
            }
            gauss(i);
        }
        printf("%.6f
    ",f[xx][yy]);
    }
  • 相关阅读:
    background-size属性的几个实用的值
    用jQuery实现旋转木马效果(带前后按钮和索引按钮)
    用jQuery制作仿网易云课堂导航菜单效果
    IE8专用hack
    jQuery的slicebox插件实现3D翻转轮播效果
    未知宽高的图片水平垂直居中的几种方法
    清除浮动的几种方法
    用canvas实现鼠标拖动绘制矩形框
    个人收藏的移动端网页布局rem解决方案
    jQuery仿3D旋转木马效果插件(带索引按钮)
  • 原文地址:https://www.cnblogs.com/mountaink/p/11459463.html
Copyright © 2011-2022 走看看