• CodeForces


    pro:给定N*M的矩阵,以及初始玩家位置。 规定玩家每次会等概率的向左走,向右走,向下走,原地不动,问走到最后一行的期望。保留4位小数。

    sol:可以列出方程,高斯消元即可,发现是三角矩阵,O(N*M)----元素个数。  也可以用反复逼近答案。 反复做,dp[i][j]=(dp[i][j+1]+dp[i][j-1]+dp[i][j]+dp[i-1][j])/d[j]+1.0  为了使逼近效果更好,我每次先左一次,再右一次。

    #include<bits/stdc++.h>
    #define rep(i,a,b) for(int i=a;i<=b;i++)
    using namespace std;
    const int maxn=1010;
    double dp[maxn][maxn]; int d[maxn];
    int main()
    {
        int N,M,x,y;
        scanf("%d%d%d%d",&N,&M,&x,&y);
        rep(i,1,M){
            d[i]=2;
            if(i>1) d[i]++;
            if(i<M) d[i]++;
        }
        rep(i,x+1,N){
            rep(t,1,20){
                rep(j,1,M) dp[i][j]=(dp[i][j+1]+dp[i][j-1]+dp[i][j]+dp[i-1][j])/d[j]+1.0;
                for(int j=M;j>=1;j--) dp[i][j]=(dp[i][j+1]+dp[i][j-1]+dp[i][j]+dp[i-1][j])/d[j]+1.0;
            }
        }
        printf("%.10lf
    ",dp[N][y]);
        return 0;
    }

    高斯消元版本:

    由于同行之间有后效性,所以我们在相邻层之间列方程,然后高斯消元。  即N次高斯消元,由于是上三角矩阵,所以每次高斯消元的复杂度是线性的:每行消去一个,然后倒着求解即可。  

    #include<bits/stdc++.h>
    #define rep(i,a,b) for(int i=a;i<=b;i++)
    using namespace std;
    const int maxn=1010;
    double a[maxn][maxn],res[maxn],ans[maxn][maxn];
    int N,M,X,Y;
    void Guass()
    {
        for(int R=N-1;R>=X;R--){
            rep(i,1,M) res[i]=ans[R+1][i];
            a[1][1]=a[M][M]=-2.0/3.0; a[1][2]=a[M][M-1]=1.0/3.0;
            res[1]=-ans[R+1][1]/3.0-1; res[M]=-ans[R+1][M]/3.0-1;
            rep(i,2,M-1){
               a[i][i-1]=a[i][i+1]=1.0/4.0;
               a[i][i]=-3.0/4.0;
               res[i]=-ans[R+1][i]/4.0-1;
            }
            rep(i,1,M-1){
                double t=a[i+1][i]/a[i][i];
                a[i+1][i]-=t*a[i][i];
                a[i+1][i+1]-=t*a[i][i+1];
                //a[i+1][i+2]-=t*a[i][i+2]; 不知道为什么这行删去了也能AC
                res[i+1]-=t*res[i];
            }
            ans[R][M]=res[M]/a[M][M];
            for(int i=M-1;i>=1;i--){
                ans[R][i]=(res[i]-a[i][i+1]*ans[R][i+1])/a[i][i];
            }
        }
    }
    int main()
    {
        scanf("%d%d%d%d",&N,&M,&X,&Y);
        if(M==1){
            printf("%.10lf
    ",2.0*(N-X));
            return 0;
        }
        Guass();
        printf("%.10lf
    ",ans[X][Y]);
        return 0;
    }
  • 相关阅读:
    OI中的小智慧
    洛谷 P2335 SDOI 2005 毒瘤 位图(也补上注释了)
    洛谷P4779 Dijkstra 模板
    洛谷 P1156 垃圾陷阱 谈论剪枝,非满分
    8/14考试 JWG
    一个好消息 JWG
    刷水题(一) JWG
    C语言运算符优先级从没像现在这样深刻体会
    cron 备忘
    CentOS
  • 原文地址:https://www.cnblogs.com/hua-dong/p/10851746.html
Copyright © 2020-2023  润新知