CF24D Broken robot
题意
有一个\(n \times m\)的矩阵。机器人从点\((x,y)\)开始等概率的往下,往右,往左走或者不动。如果再第一列,那么不会往左走,再第m列不会往右走。也就是说机器人不会走出这个格子。走到最后一行会停止。求出机器人期望行走的步数。
思路
设\(f[i][j]\)表示从\((i,j)\)走到最后一行的期望步数。
显然最后一行的答案为0
然后考虑其他行。假设\(j!=m\)并且\(j!=1\)那么有
\]
然后这个\(dp\)具有后效性,无法直接转移
通分移项可得
\]
这样对于每一行我们就可以列出来一个\(m\)元的方程组。
然后发现\(f\)数组的每一行都可以用一次高斯消元解出来。
\(j=1\)或者\(j=m\)??
和上面一样的思路,稍微改一下\(dp\)方程即可
如下
\]
\]
复杂度???
因为这个高斯消元的矩阵列出来是一个这样的矩阵

所以其实是可以\(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的更多相关文章
- cf24D. Broken robot(高斯消元)
题意 题目链接 Sol 今天上午的A题.想出来怎么做了但是没时间写了qwq 思路很简单,首先把转移方程列一下,发现每一个位置只会从下一行/左右转移过来,而且第N行都是0,那么往下转移的都可以回带. 剩 ...
- 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$ $ ...
- $CF24D\ Broken Robot\ DP+$高斯消元
Luogu Description 你收到的礼物是一个非常聪明的机器人,行走在一块长方形的木板上.不幸的是,你知道它是坏的,表现得相当奇怪(随机).该板由n行和m列的单元格组成.机器人最初是在i行和j ...
- CF 24 D. Broken robot
D. Broken robot 链接. 题意: 一个方格,从(x,y)出发,等价的概率向下,向左,向右,不动.如果在左右边缘上,那么等价的概率不动,向右/左,向下.走到最后一行即结束.求期望结束的步数 ...
- CodeForces 24D Broken robot (概率DP)
D. Broken robot time limit per test 2 seconds memory limit per test 256 megabytes input standard inp ...
- 【题解】CF24D Broken Robots(收敛性)
[题解]CF24D Broken Robots http://codeforces.com/problemset/problem/24/D 解1(不会写,口胡的) 获得一个比较显然的转移式子 \(dp ...
- CodeForces 24D Broken robot(期望+高斯消元)
CodeForces 24D Broken robot 大致题意:你有一个n行m列的矩形板,有一个机器人在开始在第i行第j列,它每一步会随机从可以选择的方案里任选一个(向下走一格,向左走一格,向右走一 ...
- 『Broken Robot 后效性dp 高斯消元』
Broken Robot Description 你作为礼物收到一个非常聪明的机器人走在矩形板上.不幸的是,你明白它已经破碎并且行为相当奇怪(随机).该板由N行和M列单元组成.机器人最初位于第i行和第 ...
- 【CF24D】Broken Robot (DP+高斯消元)
题目链接 题意:给定一个\(n\times m\)的矩阵,每次可以向→↓←移动一格,也可以原地不动,求从\((x,y)\)到最后一行的期望步数. 此题标签\(DP\) 看到上面这个肯定会想到 方法一: ...
随机推荐
- linux下编译protobuf
这里我介绍两种方法,一是直接ccmake配置,二是修改cmake文件下面的CMakeList.txt文件 第一种方法:配置ccmake 1.安装sudo apt-get install cmake-c ...
- 2019Java查漏补缺(二)
查看了公众号:java之间的整理的集和文章,文章地址 总结和搜索了一下网络知识,总结了一下: 1.String 的hashcode()方法 2.switch总结: 3.如何实现克隆 1.String ...
- Python第七天 函数 函数参数 函数里的变量 函数返回值 多类型传值 函数递归调用 匿名函数 内置函数
Python第七天 函数 函数参数 函数里的变量 函数返回值 多类型传值 函数递归调用 匿名函数 内置函数 目录 Pycharm使用技巧(转载) Python第一天 ...
- webmagic 爬取网页所有文章的标题时间作者和内容
package com.ij34; import us.codecraft.webmagic.Site; import us.codecraft.webmagic.Page; import us.co ...
- SQL SERVER 执行动态SQL EXEC
:普通SQL语句可以用Exec执行 eg: Select * from tableName Exec('select * from tableName') Exec sp_executesql N's ...
- c/c++ 多线程 层级锁
多线程 层级锁 当要同时操作2个对象时,就需要同时锁定这2个对象,而不是先锁定一个,然后再锁定另一个.同时锁定多个对象的方法:std::lock(对象1.锁,对象2.锁...) 但是,有的时候,并不能 ...
- 本地windows下搭建git的本地服务器
本地windows下搭建git的本地服务器 准备工作: 本地安装java环境,配置环境变量(略) 下载gitblit文件,百度一大堆 开始第一步: 减压gitblit压缩包到某个目录下,比如我在:H: ...
- SQLServer之创建事务未提交读
未提交读注意事项 使用 SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED 指定会话的锁定级别. 一次只能设置一个隔离级别选项,而且设置的选项将一直对那个 ...
- MySQL 索引创建及使用
索引的类型 PRIMARY KEY(主键索引): 用来标识唯一性,数据不可重复 ,主键列不能为NULL,并且每个表中有且只能有一个主键,还可以创建复合主键,即多个字段组合起来. 创建语句为: -- ...
- 进程间数据传递:Queue,Pipe 进程间数据共享:Manager
1.使用multiprocessing模块的Queue实现数据传递 ''' 进程间通讯: Queue,用法跟线程里的Queue一样,put,get 线程queue没有做序列化,进程queue做序列化了 ...