Luogu

Description

你收到的礼物是一个非常聪明的机器人,行走在一块长方形的木板上.不幸的是,你知道它是坏的,表现得相当奇怪(随机).该板由n行和m列的单元格组成.机器人最初是在i行和j列的某个单元格上.然后在每一步机器人可以到另一个单元.目的是去底层(n次)行.机器人可以停留在当前单元,向左移动,向右边移动,或者移动到当前下方的单元.如果机器人在最左边的列不能向左移动,如果它是在最右边的列不能向右移动.在每一步中,所有可能的动作都是同样可能的.返回步的预期数量达到下面的行.

Sol

这题和传纸条有点类似,不同的是机器人既能向左走又能向右走,而传纸条只能向右传.

f[i][j]表示从(i,j)走到最后一行所需要的期望步数

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

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

(j!=1&&j!=m)f[i][j]=1/4(f[i][j]+f[i][j-1]+f[i][j+1]+f[i+1][j])+1

部分状态之间可以互相转移互相影响,并不能满足DP的无后效性

所以不能线性递推,要用高斯消元直接求出状态转移方程的解

需要注意的是m=1的情况要特判

m=3时,系数矩阵如下:

-2/3  1/3    0

1/4    1/4    1/4

0        1/3    -2/3

值得一提的是,我们用f[i][j]表示从(i,j)走到最后一步的期望步数,按照行号倒序进行递推,而不是用f[i][j]表示从(x,y)到(i,j)的期望步数并正序递推.原因是,若正序递推,则还须求出(x,y)到最后一行每一个位置的概率p[n][j],计算Σp[n][j]*f[n][j]才能得到答案,较为复杂.

事实上,很多数学期望DP都会采取倒推的方式执行.

Code

关于代码实现其实还有几个值得注意的地方

1.f[i][j]数组可以滚动优化

2.因为要多次解方程组,很多人可能会每次都初始化a数组(系数矩阵).其实没有必要,只要初始化一次,并且同时记录一下c[i]=a[i+1][i]/a[i][i]就好了(没写code这句话可能暂时看不懂,看下code就会懂了鸭QwQ)

 #include<iostream>
#include<cstdio>
#include<cstring>
#define Rg register
#define il inline
#define db double
#define ll long long
#define mem(a,b) memset(a,b,sizeof(a));
#define go(i,a,b) for(Rg int i=a;i<=b;++i)
#define yes(i,a,b) for(Rg int i=a;i>=b;--i)
using namespace std;
il int read()
{
int x=,y=;char c=getchar();
while(c<''||c>''){if(c=='-')y=-;c=getchar();}
while(c>=''&&c<=''){x=(x<<)+(x<<)+c-'';c=getchar();}
return x*y;
}
const int N=;
int n,m,x,y;
db a[N][N],b[N],f[N],c[N];
il void init_a()
{
if(m==){a[][]=(db)-1.0/;return;}
a[][]=(db)-2.0/;a[][]=(db)1.0/;
a[m][m-]=(db)1.0/;a[m][m]=(db)-2.0/;
go(i,,m-)a[i][i-]=(db)1.0/,a[i][i]=(db)-3.0/,a[i][i+]=(db)/;
go(i,,m)
{
c[i]=a[i+][i]/a[i][i];
a[i+][i]-=c[i]*a[i][i];
a[i+][i+]-=c[i]*a[i][i+];
}
}
il void init_b()
{
if(m==){b[]=(db)-f[]/-;return;}
b[]=-(db)f[]/-;b[m]=-(db)f[m]/-;
go(i,,m-)b[i]=-(db)f[i]/-;
}
il void calc()
{
go(i,,m){db t=c[i];b[i+]-=t*b[i];}
f[m]=b[m]/a[m][m];
yes(i,m-,)f[i]=(b[i]-f[i+]*a[i][i+])/a[i][i];
}
int main()
{
n=read(),m=read(),x=read(),y=read();//m==1 special case !
init_a();
yes(i,n-,x){init_b();calc();}
printf("%.10lf",f[y]);
return ;
}

$CF24D\ Broken Robot\ DP+$高斯消元的更多相关文章

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  9. 【CF24D】Broken Robot (DP+高斯消元)

    题目链接 题意:给定一个\(n\times m\)的矩阵,每次可以向→↓←移动一格,也可以原地不动,求从\((x,y)\)到最后一行的期望步数. 此题标签\(DP\) 看到上面这个肯定会想到 方法一: ...

随机推荐

  1. pytorch旧版安装

    https://pytorch.org/get-started/previous-versions 可以直接下载文件 用 pip 直接在下载目录安装就可以了

  2. oralce函数 next_day(d1[,c1])

    [功能]:返回日期d1在下周,星期几(参数c1)的日期 [参数]:d1日期型,c1为字符型(参数),c1默认为j(即当前日期) [参数表]:c1对应:星期一,星期二,星期三……星期日 [返回]:日期 ...

  3. 2011-04-21 运程连Oracle的方法

    oracle无法远程连接重要原因,即使防火墙开放1521端口, 但是返回包可能是随机端口,所以仍有可能被防火墙阻止. 解决方法: 在注册表中增加一个字符串值如下.可解决 花费两天找到的方法 [HKEY ...

  4. oracle连接多个扫描

    如果你对一个列和一组有限的值进行比较, 优化器可能执行多次扫描并对结果进行合并连接. 举例: SELECT * FROM LODGING WHERE MANAGER IN (‘BILL GATES’, ...

  5. fakeroot与sudo的区别

    fakeroot 可以用来模拟 root 权限,以便建立特定权限与档案拥有者的压缩文件案(tar, ar, .deb 等).透过 LD_PRELOAD 的 dynamic loader 功能,用户不必 ...

  6. HMM(隐马尔科夫)用于中文分词

    隐马尔可夫模型(Hidden Markov Model,HMM)是用来描述一个含有隐含未知参数的马尔可夫过程. 本文阅读了2篇blog,理解其中的意思,附上自己的代码,共同学习. 一.理解隐马尔科夫 ...

  7. TortoiseSVN各种状态

    黄色感叹号(有冲突): --这是有冲突了,冲突就是说你对某个文件进行了修改,别人也对这个文件进行了修改,别人抢在你提交之前先提交了,这时你再提交就会被提示发生冲突,而不允许你提交,防止你的提交覆盖了别 ...

  8. java 多线程之synchronized wait/notify解决买票问题

    一.Java线程具有五中基本状态 新建状态(New):当线程对象对创建后,即进入了新建状态,如:Thread t = new MyThread(); 就绪状态(Runnable):当调用线程对象的st ...

  9. 解决vscode电脑卡顿问题

    在安装了vscode之后,发现电脑很卡,cpu使用率高达100%. 解决方法1: 打开vscode之后,点击文件==>首选项==>设置搜索设置search.followSymlinks然后 ...

  10. 关于 vue 生命周期 钩子函数 事件

    vue实例有一个完整的生命周期,也就是从开始创建.初始化数据.编译模板.挂载Dom.渲染->更新->渲染.卸载等一系列过程,我们称这是vue的生命周期. 通俗的将就是vue实例从创建到销毁 ...