zoukankan      html  css  js  c++  java
  • CF24D Broken robot

    CF

    洛咕

    题意:n行m列格子.机器人最初是在第i行第j列的格子上.目的是去第n行任意一个格子.机器人每一步可以停留在当前格子,向左移动,向右移动,或者移动到当前下方的格子上.如果机器人在最左边的列不能向左移动,如果它是在最右边的列不能向右移动.在每一步中,所有可能的动作的概率相同.求机器人到达第n行所需行动次数的期望值.((1<=n,m<=1000))

    分析:设(f[i][j])表示机器人从位置((i,j))走到最后一行所需行动次数的期望值.

    (f[i][1]=frac{1}{3}(f[i][1]+f[i][2]+f[i+1][1])+1)如果当前在第1列,则只有不动,向右和向下三种情况可以走;

    (f[i][m]=frac{1}{3}(f[i][m]+f[i][m-1]+f[i+1][m])+1)如果当前在第m列,则只有不动,向左和向下三种情况可以走;

    否则,(f[i][j]=frac{1}{4}(f[i][j]+f[i][j-1]+f[i][j+1]+f[i+1][j])+1)

    但是,根据转移方程我们发现第i行的状态受第i+1行的状态的影响,也就是具有后效性,不能直接DP.故考虑从i+1推出i;

    (f[i+1][j])看作已知数,则上述转移方程可以写成一元一次方程,共M个方程,考虑高斯消元.注意到不论题目如何,矩阵的系数都是有规律的,设M=5,则系数矩阵为

    [left{ egin{matrix} -frac{2}{3} & frac{1}{3} & 0 & 0 & 0\ frac{1}{4} & -frac{3}{4} & frac{1}{4} & 0 & 0 \ 0 & frac{1}{4} & -frac{3}{4} & frac{1}{4} & 0 \ 0 & 0 & frac{1}{4} & -frac{3}{4} & frac{1}{4}\ 0 & 0 & 0 & frac{1}{3} & -frac{2}{3} end{matrix} ight} ]

    //#include<bits/stdc++.h>
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    using namespace std;
    inline int read(){
        int s=0,w=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){s=s*10+ch-'0';ch=getchar();}
        return s*w;
    }
    const int N=1005;
    double a[N][N],f[N][N];
    int main(){
        int n=read(),m=read(),x=read(),y=read();
        if(x==n){puts("0.0000000000");return 0;}
        if(m==1){printf("%.10lf",(n-x)*2.0);return 0;}
    //两个特判.
        for(int i=n-1;i>=x;--i){
    		a[1][1]=a[m][m]=-2.0/3.0;
    		a[1][2]=a[m][m-1]=1.0/3.0;
    		a[1][m+1]=-f[i+1][1]/3.0+1;
    		a[m][m+1]=-f[i+1][m]/3.0+1;
    		for(int j=2;j<m;++j){
    	    	a[j][j]=-3.0/4.0;
    	    	a[j][j-1]=a[j][j+1]=1.0/4.0;
    	    	a[j][m+1]=-f[i+1][j]/4.0+1;
    		}//以上都是高斯消元对矩阵赋初值
    		for(int j=1;j<m;++j){
    	    	double cnt=1.0*a[j+1][j]/a[j][j];
    	    	a[j+1][j+1]-=a[j][j+1]*cnt;
    	    	a[j+1][m+1]-=a[j][m+1]*cnt;
    		}//从上往下高斯消元
    		for(int j=m;j>1;--j){
    	    	double cnt=1.0*a[j-1][j]/a[j][j];
    	    	a[j-1][m+1]-=a[j][m+1]*cnt;
    		}//从下往上回代
    		for(int j=1;j<=m;++j)
    	    	f[i][j]=a[j][m+1]/a[j][j];//保存结果
        }
        printf("%.10lf
    ",abs(f[x][y]));//不知道为什么我答案每次输出的正好是负数
        return 0;
    }
    
    
  • 相关阅读:
    vue--一些预设属性
    vue--vux框架的使用
    vue--vConsole
    vue--音乐播放器
    vue--使用vue-cli构建项目
    vue--实例化对象
    vue--数据显示模版上
    CSS--交互效果
    Git SSH公钥配置
    gradle配置国内镜像
  • 原文地址:https://www.cnblogs.com/PPXppx/p/11047388.html
Copyright © 2011-2022 走看看