[CodeForces - 1225E]Rock Is Push 【dp】【前缀和】
[CodeForces - 1225E]Rock Is Push 【dp】【前缀和】
标签:题解 codeforces题解 dp 前缀和
题目描述
Time limit
2000 ms
Memory limit
524288 kB
Source
Technocup 2020 - Elimination Round 2
Tags
binary search dp *2200
Site
https://codeforces.com/problemset/problem/1225/E
题面
Example
Input1
1 1
.
Output1
1
Input2
2 3
...
..R
Output2
0
Input3
4 4
...R
.RR.
.RR.
R...
Output3
4
题目大意
给定\(n, m\),和一张长宽分别为\(n,m\)的地图。\(\cdot\)代表可以通过,\(R\)代表岩石,无法通过。一个人从左上\((1,1)\)出发,想要到达右下\((n, m)\),他每步只能向下或向右走一格。其间他可以推动与他相邻的一连串岩石一格,根据他从上一步到达这格的方向,但不能将岩石推出地图。问一共有多少条不同的走法?
例如,
\(n = 4, m = 4\),地图为
\]
有如下四条路径,用\(PushD\)代表向下推岩石,用\(PushR\)代表向右推岩石:
- \((1,1) \to (2,1) \to(3,1) \to PushR \to(3,2) \to(4,2) \to(4,3) \to(4,4)\)
- \((1,1) \to(2,1)\to PushR \to(2,2)\to PushD \to(3,2)\to PushR \to(3,3)\to (4,3)\to (4,4)\)
- \((1,1) \to(1,2)\to PushD \to(2,2)\to PushR \to(2,3)\to PushD \to(3,3)\to (3,4)\to (4,4)\)
- \((1,1) \to(1,2)\to (1,3)\to PushD \to(2,3)\to (2,4)\to (3,4)\to (4,4)\)
解析
询问从\((1,1)\)走到\((n, m)\)的路径条数,我们也可以反过考虑从\((n, m)\)走到\((1,1)\)的路径条数。
我们令\(dpR[i][j]\)表示从\((i,j)\)的右边一格即从\((i, j + 1)\)到达\((i,j)\)的路径条数,令\(dpD[i][j]\)表示从\((i,j)\)的下边一格即从\((i + 1, j)\)到达\((i,j)\)的路径条数。令\(kD, kR\)分别为从\((i,j)\)到此列最下端和此行最右端的岩石总数。因为岩石可以向右推至地图边缘,所以我们易得$$dpD[i][j] = \sum_{t=i + 1}^{n - kD}dpR[t][j].$$将此列中行坐标在区间\([i+1, n-kD]\)的全部能从右边到达的路径条数都加入\(dpD[i][j]\)中。
计算\(dpD\)示意图
同理,我们可得$$dpR[i][j] = \sum_{t=j + 1}^{m - kR}dpD[i][t].$$为了得到每点的\(kR,kD\),我们需要分别预处理一下每行每列从右至左,从下至上的岩石数量的前缀和。
\((i,j)\)以右(包括\((i,j)\))的全部岩石数量:\(numR[i][j] = numR[i][j + 1] + (s[i][j] == \,'R')\);
\((i,j)\)以下(包括\((i,j)\))的全部岩石数量:\(numD[i][j] = numD[i + 1][j] + (s[i][j] == \,'R')\)。
计算岩石总数前缀和
看到如上的累加公式,我们很容易想到要用前缀和来处理。否则时间复杂度会升到立方。
我们令$$ sumD[i][j] = sumD[i][j + 1] + dpD[i][j], \ sumR[i][j] = sumR[i + 1][j] + dpR[i][j].$$
则原公式可优化为$$\begin{cases}dpD[n][m] = dpR[n][m] = 1, \dpD[i][j] = \sum_{t=i + 1}^{n - numD[i][j]}dpR[t][j] = sumR[i + 1][j] - sumR[n - numD[i][j] + 1][j], \ dpR[i][j]= \sum_{t=j + 1}^{m - numR[i][j]}dpD[i][t] = sumD[i][j + 1] - sumD[i][m - numR[i][j] + 1] \end{cases}.$$最后答案即为\(dpD[1][1] + dpR[1][1]\),注意随时取模。
存在两种情况需要特判,详见代码。
以第三个样例为例试举两例,
计算(2,1)的\(dpD\)和\(dpR\)
计算(1,1)的\(dpD\)和\(dpR\)
通过代码
/*
Status
Accepted
Time
108ms
Memory
102804kB
Length
1284
Lang
GNU G++11 5.1.0
Submitted
2019-12-23 18:13:00
RemoteRunId
67463663
*/
#include <bits/stdc++.h>
using namespace std;
const int MOD = 1e9 + 7; //随时取模.
const int MAXN = 2e3 + 50;
char s[MAXN][MAXN];
int numD[MAXN][MAXN], numR[MAXN][MAXN], sumD[MAXN][MAXN], sumR[MAXN][MAXN], dpD[MAXN][MAXN], dpR[MAXN][MAXN];
int n, m;
int main()
{
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; i ++)
scanf("%s", s[i] + 1);
if(s[1][1] == 'R' || s[n][m] == 'R'){ //第一种特判情况,起点或终点被岩石占上,则没有路径可以到达.
printf("0");
return 0;
}
if(n == 1 && m == 1){ //第二种特判情况,地图大小为1*1,则直接输出1.
printf("1");
return 0;
}
for(int i = n; i >= 1; i --){ //从右下开始预处理岩石总数前缀和.
for(int j = m; j >= 1; j --){
numD[i][j] = numD[i + 1][j] + (s[i][j] == 'R');
numR[i][j] = numR[i][j + 1] + (s[i][j] == 'R');
}
}
sumD[n][m] = sumR[n][m] = dpD[n][m] = dpR[n][m] = 1;
for(int i = n; i >= 1; i --){ //从右下开始状态转移.
for(int j = m; j >= 1; j --){
if(i == n && j == m) continue;
dpD[i][j] = (sumR[i + 1][j] - sumR[n - numD[i + 1][j] + 1][j]) % MOD;
dpR[i][j] = (sumD[i][j + 1] - sumD[i][m - numR[i][j + 1] + 1]) % MOD;
sumD[i][j] = (sumD[i][j + 1] + dpD[i][j]) % MOD;
sumR[i][j] = (sumR[i + 1][j] + dpR[i][j]) % MOD;
}
}
printf("%d", (dpR[1][1] + dpD[1][1] + 2ll * MOD) % MOD); //得出答案.
return 0;
}
[CodeForces - 1225E]Rock Is Push 【dp】【前缀和】的更多相关文章
- Codeforces Round #596 (Div. 2, based on Technocup 2020 Elimination Round 2) E. Rock Is Push dp
E. Rock Is Push You are at the top left cell (1,1) of an n×m labyrinth. Your goal is to get to the b ...
- Codeforces 332B Maximum Absurdity(DP+前缀和处理)
题目链接:http://codeforces.com/problemset/problem/332/B 题目大意:给你n个数和一个整数k,要求找到不相交的两个长度为k的区间,使得区间和最大,输出这两个 ...
- Codeforces 1247E. Rock Is Push
传送门 显然考虑 $dp$ ,设 $fx[i][j]$ 表示从 $(i,j)$ 出发往下走一格,最终到达 $(n,m)$ 的方案数,$fy[i][j]$ 表示从 $(i,j)$ 出发往右走一格,最终到 ...
- CodeForces 816B Karen and Coffee(前缀和,大量查询)
CodeForces 816B Karen and Coffee(前缀和,大量查询) Description Karen, a coffee aficionado, wants to know the ...
- HDU 2829 区间DP & 前缀和优化 & 四边形不等式优化
HDU 2829 区间DP & 前缀和优化 & 四边形不等式优化 n个节点n-1条线性边,炸掉M条边也就是分为m+1个区间 问你各个区间的总策略值最少的炸法 就题目本身而言,中规中矩的 ...
- [BZOJ 3625] [Codeforces 438E] 小朋友的二叉树 (DP+生成函数+多项式开根+多项式求逆)
[BZOJ 3625] [Codeforces 438E] 小朋友的二叉树 (DP+生成函数+多项式开根+多项式求逆) 题面 一棵二叉树的所有点的点权都是给定的集合中的一个数. 让你求出1到m中所有权 ...
- [Codeforces712D] Memory and Scores(DP+前缀和优化)(不用单调队列)
[Codeforces712D] Memory and Scores(DP+前缀和优化)(不用单调队列) 题面 两个人玩游戏,共进行t轮,每人每轮从[-k,k]中选出一个数字,将其加到自己的总分中.已 ...
- T2988 删除数字【状压Dp+前缀和优化】
Online Judge:从Topcoder搬过来,具体哪一题不清楚 Label:状压Dp+前缀和优化 题目描述 给定两个数A和N,形成一个长度为N+1的序列,(A,A+1,A+2,...,A+N-1 ...
- [CF467C] George and Job - DP,前缀和
简单dp + 前缀和 你谷这乱标难度的风气真是-- #include <bits/stdc++.h> using namespace std; #define int long long ...
随机推荐
- php array_combine()函数 语法
php array_combine()函数 语法 作用:通过合并两个数组来创建一个新数组,其中的一个数组是键名,另一个数组的值为键值.dd马达价格 语法:array_combine(keys,valu ...
- 【2019 Multi-University Training Contest 8】
01: 02: 03:https://www.cnblogs.com/myx12345/p/11655876.html 04: 05: 06:https://www.cnblogs.com/myx12 ...
- UE4 中的Blutilities
该功能是为编辑器中的简单扩展功能而设置的. 一般而言用蓝图在编辑器中做功能扩展都会用到Construction Script,但该功能有一些缺陷: 首先在actor发生任何变化(包括Transform ...
- 如何利用阿里视频云开源组件,快速自定义你的H5播放器?
摘要: Aliplayer希望提供一种方便.简单.灵活的机制,让客户能够扩展播放器的功能,并且Aliplayer提供一些组件的基本实现,用户可以基于这些开源的组件实现个性化功能,比如自定义UI和自己A ...
- linux的shell脚本运行python程序
可以说和windows里的bat是一样的. python3 /opt/pyweibo/get_user_info.py 104501 104502 104503
- MySql使用mysqldump 导入与导出方法总结
导出数据库数据:首先打开cmd进入MySQL的bin文件夹下 1.导出education数据库里面的users表的表数据和表结构(下面以users表为例) mysqldump -u[用户名] -h[i ...
- day22—一个AngularJS框架应用toDoList
转行学开发,代码100天——2018-04-07 今天用AngularJS照着课程写了一个案例,即toDoList,记事清单效果. 主要实现以下效果: 1.通过文本框添加内容,同时添加事件列表.主要用 ...
- Jenkins持续集成_01_Mac安装配置
前言 Jenkins是一款开源 CI&CD 软件,用于自动化各种任务,包括构建.测试和部署软件.在自动化测试中,用来持续集成,跑定时任务进行定时自动化监测.更详细介绍可查看jenkins官网: ...
- 阅读笔记05-架构师必备最全SQL优化方案(1)
一.优化的哲学 1.优化可能带来的问题? 优化不总是对一个单纯的环境进行,还很可能是一个复杂的已投产的系统: 优化手段本来就有很大的风险,只不过你没能力意识到和预见到: 任何的技术可以解决一个问题,但 ...
- python网络编程之粘包
一.什么是粘包 须知:只有TCP有粘包现象,UDP永远不会粘包 粘包不一定会发生 如果发生了:1.可能是在客户端已经粘了 2.客户端没有粘,可能是在服务端粘了 首先需要掌握一个socket收发消息的原 ...