题目链接

题意:给定一个\(n\times m\)的矩阵,每次可以向→↓←移动一格,也可以原地不动,求从\((x,y)\)到最后一行的期望步数。

此题标签\(DP\)

看到上面这个肯定会想到

方法一: \(f[i][j]\)表示表示从\((x,y)\)走到\((i,j)\)的期望步数,正推

方法二: \(f[i][j]\)表示从\((i,j)\)走到最后一行的期望步数,倒推

事实上,方法二更优秀。

因为如果用方法一,我们要求的答案就是\(\frac{\sum f[\text{最后一行}][\text{每个位置}]}{m}\)

而如果我们用方法二,答案就是\(f[x][y]\),省时又省力。

所以我们就用方法二。

然而上面两种方案都是有后效性的,因为\(f[i][j]\)取决与\(f[i-1][j](\text{或}f[i+1][j],f[i][j-1],f[i][j+1]\)甚至他本身,我们无法确定一个正确的递推顺序。

这时就要用\(DP\)套高斯消元了。

显然\(f[\text{最后一行}][\text{每个位置}]\)都为\(0\),于是枚举行,从\(n-1\)枚举到\(x\)。

先把状态转移方程写出来。

\(f[i][j]=\begin{cases}\ \frac{1}{3}(f[i][j]+f[i][j+1]+f[i+1][j])\ (j=1)\\ \frac{1}{4}(f[i][j-1]+f[i][j]+f[i][j+1]+f[i+1][j])\ (j!=1,j!=m)\\ \frac{1}{3}(f[i][j]+f[i][j-1]+f[i+1][j])\ (j=m)\end{cases}\)

可以发现,方程中\(f[i+1][j]\)固定出现,而这是我们已知的(最后一行均为\(0\),一行一行往上倒推),于是考虑移项。

以\(j=1\)为例,

\[f[i][j]=\frac{1}{3}(f[i][j]+f[i][j+1]+f[i+1][j])
\]

移项得

\[-\frac{1}{3}f[i+1][j]=\frac{1}{3}(-2f[i][j]+f[i][j+1]+f[i+1][j])
\]

于是我们便得到了\(m\)个一次方程,用高斯消元即可解出每一行所有的\(f\)值。

高斯消元理论复杂度\(O(n^3)\),但是我们仔细观察本题,每行事实上只有两个数需要消元,所以我们可以在\(O(m)\)的时间复杂度里完成高斯消元,算法总时间复杂度\(O(nm^2)\)。

#include <cstdio>
#include <cstdlib>
const int MAXN = 1010;
double f[MAXN][MAXN];
double M[MAXN][MAXN];
int n, m, x, y;
void Gauss(){ //高斯消元
for(int i = 1; i <= m; ++i){
double tmp = 1.0 / M[i][i]; //系数化一
M[i][i] *= tmp; M[i][m + 1] *= tmp;
if(i == m) break;
M[i][i + 1] *= tmp;
tmp = M[i + 1][i] / M[i][i]; //下一行消掉该元
M[i + 1][i] -= tmp * M[i][i]; M[i + 1][i + 1] -= tmp * M[i][i + 1]; M[i + 1][m + 1] -= tmp * M[i][m + 1];
}
for(int i = m - 1; i; --i) M[i][m + 1] -= M[i + 1][m + 1] * M[i][i + 1]; //回代
}
int main(){
scanf("%d%d%d%d", &n, &m, &x, &y);
for(int i = n - 1; i >= x; --i){
M[1][1] = -1.0 + 1.0 / 3; //
M[1][2] = 1.0 / 3;
for(int j = 2; j < m; ++j){
M[j][m + 1] = (-f[i + 1][j]) / 4.0 - 1;
M[j][j] = -1.0 + 1.0 / 4;
M[j][j - 1] = M[j][j + 1] = 1.0 / 4;
}
M[m][m] = -1.0 + 1.0 / 3;
M[m][m - 1] = 1.0 / 3;
if(m == 1) M[1][1] = -1.0 + 1.0 / 2;
M[1][m + 1] = (-f[i + 1][1]) / 3.0 - 1;
M[m][m + 1] = (-f[i + 1][m]) / 3.0 - 1; //构建矩阵
if(m == 1) M[m][m + 1] = (-f[i + 1][m]) / 2.0 - 1; //特判$m=1$的情况
Gauss();
for(int j = 1; j <= m; ++j)
f[i][j] = M[j][m + 1];
}
printf("%.10lf", f[x][y]);
return 0;
}

【CF24D】Broken Robot (DP+高斯消元)的更多相关文章

  1. $CF24D\ Broken Robot\ DP+$高斯消元

    Luogu Description 你收到的礼物是一个非常聪明的机器人,行走在一块长方形的木板上.不幸的是,你知道它是坏的,表现得相当奇怪(随机).该板由n行和m列的单元格组成.机器人最初是在i行和j ...

  2. codeforces 24d Broken robot 期望+高斯消元

    题目传送门 题意:在n*m的网格上,有一个机器人从(x,y)出发,每次等概率的向右.向左.向下走一步或者留在原地,在最左边时不能向右走,最右边时不能像左走.问走到最后一行的期望. 思路:显然倒着算期望 ...

  3. BZOJ 3270: 博物馆 [概率DP 高斯消元]

    http://www.lydsy.com/JudgeOnline/problem.php?id=3270 题意:一张无向图,一开始两人分别在$x$和$y$,每一分钟在点$i$不走的概率为$p[i]$, ...

  4. BZOJ_3143_[Hnoi2013]游走_期望DP+高斯消元

    BZOJ_3143_[Hnoi2013]游走_期望DP+高斯消元 题意: 一个无向连通图,顶点从1编号到N,边从1编号到M. 小Z在该图上进行随机游走,初始时小Z在1号顶点,每一步小Z以相等的概率随机 ...

  5. BZOJ_1778_[Usaco2010 Hol]Dotp 驱逐猪猡_概率DP+高斯消元

    BZOJ_1778_[Usaco2010 Hol]Dotp 驱逐猪猡_概率DP+高斯消元 题意: 奶牛们建立了一个随机化的臭气炸弹来驱逐猪猡.猪猡的文明包含1到N (2 <= N <= 3 ...

  6. LightOJ - 1151概率dp+高斯消元

    概率dp+高斯消元 https://vjudge.net/problem/LightOJ-1151 题意:刚开始在1,要走到100,每次走的距离1-6,超过100重来,有一些点可能有传送点,可以传送到 ...

  7. 【BZOJ3640】JC的小苹果 概率DP+高斯消元

    [BZOJ3640]JC的小苹果 Description 让我们继续JC和DZY的故事. “你是我的小丫小苹果,怎么爱你都不嫌多!” “点亮我生命的火,火火火火火!” 话说JC历经艰辛来到了城市B,但 ...

  8. 【bzoj1778】[Usaco2010 Hol]Dotp 驱逐猪猡 矩阵乘法+概率dp+高斯消元

    题目描述 奶牛们建立了一个随机化的臭气炸弹来驱逐猪猡.猪猡的文明包含1到N (2 <= N <= 300)一共N个猪城.这些城市由M (1 <= M <= 44,850)条由两 ...

  9. BZOJ3270 博物館 概率DP 高斯消元

    BZOJ3270 博物館 概率DP 高斯消元 @(XSY)[概率DP, 高斯消元] Description 有一天Petya和他的朋友Vasya在进行他们众多旅行中的一次旅行,他们决定去参观一座城堡博 ...

随机推荐

  1. jmeter多用户登录跨线程组操作传值

    项目需求: 需要登录两个用户A.B,用户A操作完后会通知B,然后B再操作,B操作完结束或者再通知A. 实现思路: 1. 设置两个线程组Ⅰ.Ⅱ,组Ⅰ添加cookie管理器,里面添加用户A的操作:组Ⅱ添加 ...

  2. 基于jersey和Apache Tomcat构建Restful Web服务(一)

    基于jersey和Apache Tomcat构建Restful Web服务(一) 现如今,RESTful架构已然成为了最流行的一种互联网软件架构,它结构清晰.符合标准.易于理解.扩展方便,所以得到越来 ...

  3. OpenCV入门:(一:安装与配置)

    看到的不是自己的,只有写下来的才是自己的,上次接触OpenCV实在三个月前,亢奋的看完了OpenCV自带的入门文档,觉得对图形处理有了一点点了解,现在三个月过去了,由于学习需要,想深入了解OpenCV ...

  4. Django admin源码剖析

    单例模式 单例模式(Singleton Pattern)是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在.当你希望在整个系统中,某个类只能出现一个实例时,单例对象就能派上用场. ...

  5. PHP管理供下载的APK文件

    当我们开发的APP多的时候,把所有的APK文件统一放到一个目录中管理,是一个不错的选择: 管理的方法有很多,这里说一种: 1..创建目录结构,先创建根目录download,在根目录中创建项目目录,在项 ...

  6. react实现页面切换动画效果

    一.前情概要 注:(我使用的路由是react-router4)     如下图所示,我们需要在页面切换时有一个过渡效果,这样就不会使页面切换显得生硬,用户体验大大提升:     but the 问题是 ...

  7. Python中send()和sendall()的区别

    Python中send()和sendall()的区别 估计每个学习Python网络编程的人,都会遇到过这样的问题: send()和sendall()到底有什么区别? send()和sendall()原 ...

  8. 对SE的认识

    对SE的认识 简述 “架构师”,也就是SE,总是给外人一种比较牛逼的感觉,其实踏实做开发的真的很少关注这个title. 抛开这个名词,这个角色的存在的确有一定的意义,因为项目中需要一个能“带领大家前进 ...

  9. RDL/RDLC批量单据打印

    使用RDL或RDLC进行单据打印时,单张单据打印比较直观简单,无需说明.下面我们来谈一下批量单据打印的实现方法.以下以RDL的ReportBuilder设计环境为例进行讲解,RDLC.VS设计环境同理 ...

  10. struts2 action中获取request session application的方法

    共四种方式: 其中前两种得到的是Map<String,Object>  后两种得到的才是真正的request对象 而Map就是把request对象中的属性取出做成了键值对而已. [方法一] ...