zoukankan      html  css  js  c++  java
  • 【codeforces 24D】损坏的机器人

    题目大意:有一只坏了的机器人站在一个nm的网格里,初始位置在(x,y)。现在每个单位时间内它会随机选左右下三个方向走,如果它随机的方向会走出网格就不会往这个方向走。当然这个机器人也可能原地停留一个单位时间。求机器人走到第n行的期望时间。

    只能说这题出得太吼辣~

    我们用f[i][j]表示从(i,j)这个点走到第n行所需要的期望时间。那么我们显然得到:

    f[i][1]=(f[i][1]+f[i][2]+f[i+1][1])/3+1;

    f[i][j]=(f[i][j-1]+f[i][j]+f[i][j+1]+f[i+1][j])/4+1; j∈[2,m-1] 

    f[i][m]=(f[i][m]+f[i][m-1]+f[i+1][m])/3+1;

    如果对上述的方程进行simple的高斯消元,很明显是不行的.....

    但还是要消一遍先~,得到:

    f[i][1]=(3+f[i][2]+f[i+1][1])/2;

    f[i][j]=(4+f[i][j+1]+f[i][j-1]+f[i+1][j])/3;

    f[i][m]=(3+f[i][m-1]+f[i+1][m])/2;

    不妨设f[i+1]是已知的,那么,我们对该式子做一些细微调整。

    以f[i][1]举例 f[i][1] = (3+f[i][2]+f[i+1][1])/2 = (3+f[i+1][1])/3+1/2f[i][2]。

    我们设(3+f[i+1][1])/3为A,1/2为B。

    则f[i][2]= (4+f[i][3]+f[i][1]+f[i+1][j])/3 = (4+f[i][3]+A+B*f[i][2]+f[i+1][2])/3 

    化简后得到 f[i][2]=(4+f[i][3]+A+f[i+1][2])/(3-B)。

    与化简f[1]的方式相同,将f[i][2]化为A+Bf[i+3],不难得到F[i][2]=(4+A+f[i+1][2])/(3-B) + 1/(3-B)*f[i][3],即A’=(4+A+C)/(3-B),B'=1/(3-B)。 f[i][3...m-1]的推法与f[i][2]相同。(C为f[i+1][2])

    下面考虑f[i][m],在此之前,我们已经求得f[i][m-1]=A+B*f[i][m]。 通过前面的推论我们得知:f[i][m]=(3+f[i][m-1]+f[i+1][m])/2,代入后得到f[i][m]=(3+A+B*f[i][m]+f[i+1][m])/2。

    化简后得到f[i][m]=(3+A+f[i+1][m])/(2-B)。f[i][m]的准确值终于被求出来了.....,由于先前的f[i][j]均推出了f[i][j]=A+B*f[i][j+1],所以该行的所有f值将全部求出。

    这一过程重复n-x+1次即可。时间复杂度为O((n-x+1)*m)。

    本题有个小坑:当m=1时,上文描述的转移无效,此情况下转移为f[i][1]=f[i+1][1]+2。(我就是忘记加这个特判所以没有1A)

     

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #define M 1010
     5 using namespace std;
     6 double f[M][M]={0},a[M]={0},b[M]={0};
     7 
     8 int main(){
     9     int n,m,x,y; scanf("%d%d%d%d",&n,&m,&x,&y);
    10     n=n-x+1; if(m==1) f[1][y]=(n-1)*2;
    11     else
    12     for(int i=n-1;i;i--){
    13         memset(a,0,sizeof(a)); memset(b,0,sizeof(b));
    14         a[1]=(3+f[i+1][1])/2.; b[1]=1./2.;
    15         for(int j=2;j<m;j++){
    16             double c=f[i+1][j];
    17             a[j]=(4.+a[j-1]+c)/(3-b[j-1]);
    18             b[j]=1./(3-b[j-1]);
    19         }
    20         f[i][m]=(3.+a[m-1]+f[i+1][m])/(2.-b[m-1]);
    21         for(int j=m-1;j;j--){
    22             f[i][j]=a[j]+b[j]*f[i][j+1];
    23         }
    24     }
    25     printf("%.10lf
    ",f[1][y]);
    26 }
  • 相关阅读:
    K近邻(K Nearest Neighbor-KNN)原理讲解及实现
    Bisecting KMeans (二分K均值)算法讲解及实现
    KMeans (K均值)算法讲解及实现
    NodeJs使用async让代码按顺序串行执行
    NodeJs递归删除非空文件夹
    NodeJs之配置文件管理
    NodeJs针对Express框架配置Mysql进行数据库操作
    在Express中使用Multiparty进行文件上传及POST、GET参数获取
    Linux操作命令
    SftpUtil FTP文件上传
  • 原文地址:https://www.cnblogs.com/xiefengze1/p/7728018.html
Copyright © 2011-2022 走看看