[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 ...
随机推荐
- python学习笔记(十八)python操作excel
python操作excel需要安装通过pip安装xlwt, xlrd这两个模块: pip install xlwt pip insall xlrd 操作excel ,写入excel: import x ...
- Android逆向之旅---解析编译之后的Dex文件格式
一.前言 新的一年又开始了,大家是否还记得去年年末的时候,我们还有一件事没有做,那就是解析Android中编译之后的classes.dex文件格式,我们在去年的时候已经介绍了: 如何解析编译之后的xm ...
- 20180910-Java 文档注释
Java 文档注释 Java只是三种注释方式.前两种分别是// 和/* */,第三种被称作说明注释,它以/** 开始,以 */结束. // /* */ /** */ 说明注释允许你在程序中嵌入关于程序 ...
- CF 1182F Maximum Sine——根号算法
题目:http://codeforces.com/contest/1182/problem/F 注意有绝对值. 那么就是 k*p 对 q 取模,找最接近 \(\frac{q}{2}\) 的结果. 也就 ...
- 牛客网暑期ACM多校训练营(第五场) F - take —— 期望+树状数组+逆元
看到一篇好的博客特意转出来观摩大佬:转:https://blog.csdn.net/greybtfly/article/details/81413526 题目大意:给n个箱子排成一排,从头到尾按顺序依 ...
- Jira中的Tempo查看component以及issue的工作量汇总
在右侧group by的地方,同时选中component和issue
- 仅对原表新增列的全量数据.csv
w
- day09—css布局解决方案之全屏布局
转行学开发,代码100天——2018-03-25 今天,本文记录全屏布局的的方法.全屏布局,即滚动条不是全局滚动条,而是出现在内容区域内,:浏览器变大时,撑满窗口. 如:设置下图中布局,其中top区, ...
- ajax总结及案例
一.实验简介 目的:检验输入登录名在数据库中是否存在,如果存在,当鼠标移出登录名框后,会提示用户名已存在,并且鼠标指针自动回到登录名框内. 操作步骤: 1.获取登录名的值 2.根据获取的登录名,组织查 ...
- Learn Python the hard way, ex39 列表的操作
#!/usr/bin/python #coding:utf-8 ten_things = "apples oranges crows telephone light sugar" ...