[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\),地图为

\[\cdot \cdot \cdot R \\ \cdot R R \cdot \\ \cdot R R \cdot \\ R \cdot \cdot \cdot \\
\]

有如下四条路径,用\(PushD\)代表向下推岩石,用\(PushR\)代表向右推岩石:

  1. \((1,1) \to (2,1) \to(3,1) \to PushR \to(3,2) \to(4,2) \to(4,3) \to(4,4)\)
  2. \((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)\)
  3. \((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)\)
  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】【前缀和】的更多相关文章

  1. 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 ...

  2. Codeforces 332B Maximum Absurdity(DP+前缀和处理)

    题目链接:http://codeforces.com/problemset/problem/332/B 题目大意:给你n个数和一个整数k,要求找到不相交的两个长度为k的区间,使得区间和最大,输出这两个 ...

  3. Codeforces 1247E. Rock Is Push

    传送门 显然考虑 $dp$ ,设 $fx[i][j]$ 表示从 $(i,j)$ 出发往下走一格,最终到达 $(n,m)$ 的方案数,$fy[i][j]$ 表示从 $(i,j)$ 出发往右走一格,最终到 ...

  4. CodeForces 816B Karen and Coffee(前缀和,大量查询)

    CodeForces 816B Karen and Coffee(前缀和,大量查询) Description Karen, a coffee aficionado, wants to know the ...

  5. HDU 2829 区间DP & 前缀和优化 & 四边形不等式优化

    HDU 2829 区间DP & 前缀和优化 & 四边形不等式优化 n个节点n-1条线性边,炸掉M条边也就是分为m+1个区间 问你各个区间的总策略值最少的炸法 就题目本身而言,中规中矩的 ...

  6. [BZOJ 3625] [Codeforces 438E] 小朋友的二叉树 (DP+生成函数+多项式开根+多项式求逆)

    [BZOJ 3625] [Codeforces 438E] 小朋友的二叉树 (DP+生成函数+多项式开根+多项式求逆) 题面 一棵二叉树的所有点的点权都是给定的集合中的一个数. 让你求出1到m中所有权 ...

  7. [Codeforces712D] Memory and Scores(DP+前缀和优化)(不用单调队列)

    [Codeforces712D] Memory and Scores(DP+前缀和优化)(不用单调队列) 题面 两个人玩游戏,共进行t轮,每人每轮从[-k,k]中选出一个数字,将其加到自己的总分中.已 ...

  8. T2988 删除数字【状压Dp+前缀和优化】

    Online Judge:从Topcoder搬过来,具体哪一题不清楚 Label:状压Dp+前缀和优化 题目描述 给定两个数A和N,形成一个长度为N+1的序列,(A,A+1,A+2,...,A+N-1 ...

  9. [CF467C] George and Job - DP,前缀和

    简单dp + 前缀和 你谷这乱标难度的风气真是-- #include <bits/stdc++.h> using namespace std; #define int long long ...

随机推荐

  1. python——解释型语言

    编程语言分三大类   :  低级语言  .  汇编语言 .   高级语言. 现代计算机都是基于  图灵机模型 制造的.  因此计算机的内部只能接受二进制数据.而用二进制代码  0  1  描述的指令叫 ...

  2. Dubbo学习-6-springboot整合dubbo

    1.在前面帖子和工程的基础上,这里使用springboot整合dubbo,首先创建springboot项目: https://start.spring.io/  进入spring Initializr ...

  3. asp.net+扫描仪+图片上传

    问题: IE浏览器下使用Activex插件调用客户端扫描仪扫描文件并山传,可以将纸质档案(如合同.文件.资料等)扫描并将扫描图像保存到服务器,可以用于合同管理.档案管理等. 通过插件方式调用扫描仪扫描 ...

  4. [CF959A]Mahmoud and Ehab and the even-odd game题解

    题意简述 一个数n,Mahmoud珂以取(即如果取\(k\),使\(n = n - k\))一个正偶数,Ehab珂以取一个正奇数,一个人如果不能取了(对于Mahmoud和Ehab \(n = 0\), ...

  5. 【HDOJ6684】Rikka with Game(博弈)

    题意:有一个由小写字母组成的字符串,A和B两个人轮流操作,A想让序列的字典序最大,B想最小 两人都能任意选择一位上的字母将其右移一位(a->b,b->c……z->a)或者直接结束游戏 ...

  6. What code you will get when you create a wcf library

    创建wcf服务库的时候,系统自动生成的代码 // 注意: 使用“重构”菜单上的“重命名”命令,可以同时更改代码和配置文件中的接口名“IService1”. [ServiceContract] publ ...

  7. 在reshard过程中,将会询问reshard多少slots:

    How many slots do you want to move (from 1 to 16384)?,取值范围为1~16384,其中16384为redis cluster的拥有的slots总数, ...

  8. 2019年Java Web最流行的开发框架总结

    ORM型框架:对数据进行持久化操作,例如:基于SQL的MyBatis框架和Hibernate框架. MVC型框架:从逻辑上分为视图层,控制层,模型层,各层各司其职,之间是相互调用的关系,而不是相互依赖 ...

  9. Songwriter CF1252-E(贪心)

    题意: 已知一个序列a,问能否将a映射到序列b,使得相邻元素之间的大小关系不变(三种),且相邻元素不能相差超过k,且每个元素范围在[L,R]内.如果能,求字典序最小的b. 思路: 可以设b[1]的范围 ...

  10. ECG 项目预研

    1. 数据的采集 智能安全帽,流数据,鉴于数据量大,应该是采集到云平台上,然后在云平台上对数据处理,是一种典型的物联网+大数据应用场景,考虑使用AWS或者阿里云,然后搭建Hadoop/Spark 环境 ...