CodeForces 24D 题解

题解笔记

CF24D Broken robot(robot.cpp)

时间限制 \(1s\) | 内存限制 \(250M\)

题目描述:

有一个 \(n\)\(m\) 列的矩阵,左上角的坐标为 \((1,1)\) ,右下角的坐标为 \((n,m)\) ,有一个机器人,当前坐标为 \((x,y)\) ,在不出矩阵边界的前提下,每次等概率向左,右,下走一格或原地不动,问机器人走到最后一行期望的步数。

输入格式:

第一行包含两个整数 \(n\) , \(m\)\(1 \leq n,m \leq 103\) ),第二行为两个整数 \(x\) , \(y\)

输出格式:

仅有一行,表示机器人所需移动步数的数学期望值,结果至少保留 \(4\) 位小数。

输入输出样例:

样例1输入 样例1输出 样例2输入 样例2输出
10 10
10 4
0.0000000000 10 14
5 14
18.0038068653

解题思路:

好吧,这是一道数学题。正解应该是用高斯消元推出的 dp ,但其实反复dp就可以了

分类讨论的时刻到了:

  • 如果 \(m=1\) 的话:那就只能往下走或者原地不动,所以 $ dp_{i,j}=\dfrac{dp_{i,j}+dp_{i+1,j}}{2} +1$
  • 如果 \(j=1\) 的话:那就只能往下走或者原地不动或者往右走,所以 $ dp_{i,1}=\dfrac{dp_{i,1}+dp_{i+1,1}+dp_{i,2}}{2} +1$
  • 如果 \(j=m\) 的话:那就只能往下走或者原地不动或者往左走,所以 \(dp_{i,m} = \dfrac{dp_{i,m} + dp_{i,m-1} + dp_{i+1,m}} {3} + 1\)
  • 其他:那四个方向都应该可以走,所以 \(dp_{i,j} = \dfrac{dp_{i,j} + dp_{i,j-1} + dp_{i,j+1} + dp_{i+1,j}} {4} + 1\)

反复 \(100\) 次精度铁定就够了

参考代码:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
double dp[1005][1005];
int n,m,x,y;

int main()
{
    scanf("%d%d%d%d",&n,&m,&x,&y);
    for(int i=n-1; i>=1; --i)
    {
        for(int times=0; times<=100; times++)
        {
            if(m == 1)
            {
                dp[i][1] = (dp[i][1] + dp[i+1][1]) / 2.0 + 1;
            }
            else
            {
                dp[i][1] = (dp[i][1] + dp[i][2] + dp[i+1][1]) / 3.0 + 1;
                dp[i][m] = (dp[i][m] + dp[i][m-1] + dp[i+1][m]) / 3.0 + 1;

                for(int j=m-1; j>=2; --j)
                {
                    dp[i][j] = (dp[i][j] + dp[i][j-1] + dp[i][j+1] + dp[i+1][j]) / 4.0 + 1;
                }
            }
        }
    }
    printf("%.10lf",dp[x][y]);
    return 0;
}
posted @ 2021-11-17 18:07  yhang323  阅读(34)  评论(0编辑  收藏  举报