题目链接

题意

有一个\(n \times m\)的矩阵。机器人从点\((x,y)\)开始等概率的往下,往右,往左走或者不动。如果再第一列,那么不会往左走,再第m列不会往右走。也就是说机器人不会走出这个格子。走到最后一行会停止。求出机器人期望行走的步数。

思路

设\(f[i][j]\)表示从\((i,j)\)走到最后一行的期望步数。

显然最后一行的答案为0

然后考虑其他行。假设\(j!=m\)并且\(j!=1\)那么有

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

然后这个\(dp\)具有后效性,无法直接转移

通分移项可得

\[f[i + 1][j] + 4 = 3f[i][j] - f[i][j - 1] - f[i][j + 1]
\]

这样对于每一行我们就可以列出来一个\(m\)元的方程组。

然后发现\(f\)数组的每一行都可以用一次高斯消元解出来。

\(j=1\)或者\(j=m\)??

和上面一样的思路,稍微改一下\(dp\)方程即可

如下

\[f[1][j] + 3=2f[1][j] - f[1][j+1]
\]

\[f[m][j] + 3=2f[m][j] - f[m][j-1]
\]

复杂度???

因为这个高斯消元的矩阵列出来是一个这样的矩阵

所以其实是可以\(O(m)\)的解的。

所以总复杂度是\(O(nm)\)

代码

这是一份取模版(模数为\(998244353\))的代码,直接交到\(CF\)上会\(WA\)!!!

/*
* @Author: wxyww
* @Date: 2019-03-16 08:00:47
* @Last Modified time: 2019-03-16 16:20:43
*/
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
#include<ctime>
using namespace std;
typedef long long ll;
const int mod = 998244353,N = 1010;
#define int ll
ll read() {
ll x=0,f=1;char c=getchar();
while(c<'0'||c>'9') {
if(c=='-') f=-1;
c=getchar();
}
while(c>='0'&&c<='9') {
x=x*10+c-'0';
c=getchar();
}
return x*f;
}
int Bx,By,n,m,f[N][N],g[N][N];
ll qm(ll x,ll y) {
ll ans = 1;
for(;y;y >>= 1,x = x * x % mod)
if(y & 1) ans = ans * x % mod;
return ans;
}
void solve(int x) { g[1][m + 1] = f[x + 1][1] + 3;
g[m][m + 1] = f[x + 1][m] + 3;
for(int i = 2;i < m;++i) g[i][m + 1] = f[x + 1][i] + 4; f[x][1] = g[1][1];f[x][2] = g[1][2];f[x][m + 1] = g[1][m + 1];
for(int i = 2;i <= m;++i) {
int k1 = f[x][i - 1],k2 = g[i][i - 1];
f[x][i - 1] = (1ll * f[x][i - 1] * k2 % mod - (1ll * g[i][i - 1] * k1 % mod) + mod) % mod;
f[x][i] = (1ll * f[x][i] * k2 % mod - (1ll * g[i][i] * k1 % mod) + mod)% mod;
if(i != m)
f[x][i + 1] = (1ll * f[x][i + 1] * k2 % mod - (1ll * g[i][i + 1] * k1 % mod) + mod) % mod;
f[x][m + 1] = (1ll * f[x][m + 1] * k2 % mod - (1ll * g[i][m + 1] * k1 % mod) + mod) % mod; } f[x][m] = 1ll * f[x][m + 1] * qm(f[x][m],mod - 2) % mod; f[x][m - 1] = 1ll * (g[m][m + 1] - (1ll * g[m][m] * f[x][m] % mod) + mod) % mod * qm(g[m][m - 1],mod - 2) % mod; for(int i = m - 1;i > 1;--i)
f[x][i - 1] = ((g[i][m + 1] - ((f[x][i] * g[i][i] % mod + mod)% mod) - (f[x][i + 1] * g[i][i + 1] % mod)) % mod + mod) % mod * qm(g[i][i - 1],mod - 2) % mod;
}
signed main() {
n = read(),m = read();
Bx = read(),By = read(); if(m == 1) {printf("%lld\n",2ll * (n - Bx) % mod); return 0;} g[1][1] = 2;g[1][2] = mod - 1;
g[m][m - 1] = mod - 1,g[m][m] = 2;
for(int i = 2;i < m;++i)
g[i][i] = 3,g[i][i + 1] = mod - 1,g[i][i - 1] = mod - 1; for(int i = n - 1;i >= Bx;--i) solve(i); cout<<f[Bx][By];
return 0;
}

CF24D Broken robot的更多相关文章

  1. cf24D. Broken robot(高斯消元)

    题意 题目链接 Sol 今天上午的A题.想出来怎么做了但是没时间写了qwq 思路很简单,首先把转移方程列一下,发现每一个位置只会从下一行/左右转移过来,而且第N行都是0,那么往下转移的都可以回带. 剩 ...

  2. CF24D Broken robot 后效性DP

    这题咕了好久..... 设$f[i][j]$表示从$(i,j)$到最后一行的期望步数: 则有 $ f[i][1]=\frac{1}{3}(f[i][1]+f[i][2]+f[i+1][1])+1$ $ ...

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

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

  4. CF 24 D. Broken robot

    D. Broken robot 链接. 题意: 一个方格,从(x,y)出发,等价的概率向下,向左,向右,不动.如果在左右边缘上,那么等价的概率不动,向右/左,向下.走到最后一行即结束.求期望结束的步数 ...

  5. CodeForces 24D Broken robot (概率DP)

    D. Broken robot time limit per test 2 seconds memory limit per test 256 megabytes input standard inp ...

  6. 【题解】CF24D Broken Robots(收敛性)

    [题解]CF24D Broken Robots http://codeforces.com/problemset/problem/24/D 解1(不会写,口胡的) 获得一个比较显然的转移式子 \(dp ...

  7. CodeForces 24D Broken robot(期望+高斯消元)

    CodeForces 24D Broken robot 大致题意:你有一个n行m列的矩形板,有一个机器人在开始在第i行第j列,它每一步会随机从可以选择的方案里任选一个(向下走一格,向左走一格,向右走一 ...

  8. 『Broken Robot 后效性dp 高斯消元』

    Broken Robot Description 你作为礼物收到一个非常聪明的机器人走在矩形板上.不幸的是,你明白它已经破碎并且行为相当奇怪(随机).该板由N行和M列单元组成.机器人最初位于第i行和第 ...

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

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

随机推荐

  1. linux下编译protobuf

    这里我介绍两种方法,一是直接ccmake配置,二是修改cmake文件下面的CMakeList.txt文件 第一种方法:配置ccmake 1.安装sudo apt-get install cmake-c ...

  2. 2019Java查漏补缺(二)

    查看了公众号:java之间的整理的集和文章,文章地址 总结和搜索了一下网络知识,总结了一下: 1.String 的hashcode()方法 2.switch总结: 3.如何实现克隆 1.String ...

  3. Python第七天 函数 函数参数 函数里的变量 函数返回值 多类型传值 函数递归调用 匿名函数 内置函数

    Python第七天   函数  函数参数   函数里的变量   函数返回值  多类型传值     函数递归调用   匿名函数   内置函数 目录 Pycharm使用技巧(转载) Python第一天   ...

  4. webmagic 爬取网页所有文章的标题时间作者和内容

    package com.ij34; import us.codecraft.webmagic.Site; import us.codecraft.webmagic.Page; import us.co ...

  5. SQL SERVER 执行动态SQL EXEC

    :普通SQL语句可以用Exec执行 eg: Select * from tableName Exec('select * from tableName') Exec sp_executesql N's ...

  6. c/c++ 多线程 层级锁

    多线程 层级锁 当要同时操作2个对象时,就需要同时锁定这2个对象,而不是先锁定一个,然后再锁定另一个.同时锁定多个对象的方法:std::lock(对象1.锁,对象2.锁...) 但是,有的时候,并不能 ...

  7. 本地windows下搭建git的本地服务器

    本地windows下搭建git的本地服务器 准备工作: 本地安装java环境,配置环境变量(略) 下载gitblit文件,百度一大堆 开始第一步: 减压gitblit压缩包到某个目录下,比如我在:H: ...

  8. SQLServer之创建事务未提交读

    未提交读注意事项 使用 SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED 指定会话的锁定级别. 一次只能设置一个隔离级别选项,而且设置的选项将一直对那个 ...

  9. MySQL 索引创建及使用

    索引的类型 PRIMARY KEY(主键索引):   用来标识唯一性,数据不可重复 ,主键列不能为NULL,并且每个表中有且只能有一个主键,还可以创建复合主键,即多个字段组合起来. 创建语句为: -- ...

  10. 进程间数据传递:Queue,Pipe 进程间数据共享:Manager

    1.使用multiprocessing模块的Queue实现数据传递 ''' 进程间通讯: Queue,用法跟线程里的Queue一样,put,get 线程queue没有做序列化,进程queue做序列化了 ...