题目链接

题意:给定一个\(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. NSOperation那点事儿

    1. NSOperation.NSOperationQueue 简介 NSOperation.NSOperationQueue 是苹果提供给我们的一套多线程解决方案.实际上 NSOperation.N ...

  2. Python的文件输入输出,如何追加内容,读取内容,添加内容

    python主要的文件打开的几种访问模式 模式可以为读模式('r').写模式('w')或追加模式('a'),当然还有rb.wb.ab.r+.w+.a+.rb+.wb+.ab+,然而实际从代码上我也没看 ...

  3. Scala学习笔记(一):环境搭建

    计算机领域的编程语言种类繁多,如C.C++.Java.C#等,我们知道的一般都是较为流行的编程语言,然有更多的是没听说过的,于是也就说不上关注或者使用了 一次在网上查资料时,无意间看到了“函数式编程” ...

  4. 玩转VIM之将Vim全副武装

    玩转VIM之将Vim全副武装 懒癌末期的我貌似很久没有写博客了,已经欠了多少篇在计划中的博客我已然不好意思说了.好了,言归正传,在前三篇介绍了Vim作为代码编辑器之后可能会有人说,要学习那么多指令真的 ...

  5. python之time和os模块

    1.time.time()获得的是一个时间戳,距离1970年以来多少秒 2.time.strftime(),按固定格式设置时间 import time print(time.localtime())# ...

  6. 【iOS开发】iOS CGRectGetMaxX/Y 使用

    在iOS的界面布局中我们可以使用CGRectGetMaxX 这个方法来方便的获取当前控件的x坐标值+宽度的数值,这样便可以方便布局. 同理CGRectGetMaxY是获取y坐标值+控件高度的值,当然这 ...

  7. 一个简单的NetCore项目:2 - 登录

    1-UI,登陆界面布局 PS:使用的是metronic 框架,没有用过的可以自行百度. 1.1 metronic 放在wwwroot文件夹下面 1.2  metronic 中的 open sans 使 ...

  8. 201621123033 《Java程序设计》第14周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结与数据库相关内容. 2. 使用数据库技术改造你的系统 2.1 简述如何使用数据库技术改造你的系统.要建立什么表?截图你的表设计. 2 ...

  9. tomcat 启动报错 解决办法 A child container failed during

    控制台报错: Caused by: org.apache.catalina.LifecycleException: A child container failed during start at o ...

  10. 【bzoj4002】[JLOI2015]有意义的字符串 数论+矩阵乘法

    题目描述 B 君有两个好朋友,他们叫宁宁和冉冉.有一天,冉冉遇到了一个有趣的题目:输入 b;d;n,求 输入 一行三个整数 b;d;n 输出 一行一个数表示模 7528443412579576937 ...