【CF1225E Rock Is Push】推岩石
题目描述##
你现在在一个\(n×m\)的迷宫的左上角(即点\((1,1)\)),你的目标是到达迷宫的右下角(即点\((n,m)\))。一次移动你只能向右或者是向下移动一个单位。比如在点\((x,y)\)你可以移动到点\((x+1,y)\)或点\((x,y+1)\)
迷宫中的一些点是岩石,当你移动到一个有岩石的点时岩石将被推到你移动方向的下一个点(你可以把岩石想象成推箱子游戏中的箱子),而如果那个点上也有一个岩石,它就会被按相同方向推的更远,以此类推(比如当前点右边有连着的一些岩石,你向右走一个点这些岩石就都会被向右推一个点)
这个迷宫被不可移动或是摧毁的墙包围着,石头是不允许被推到墙外或者摧毁墙的。(比如你右边有一个石头,而再往右是墙,你就不能往右移动了)
现在,请你计算出有多少种不同的可以到达终点的方案,由于方案数可能很大,结果请对\(10^9+7\)取模。两条路径中如果有任意的至少一个点不同,那就认为这两种方案是不同的。
输入格式##
输入第一行是两个正整数\(n,m\),表示迷宫的长和宽\((1≤n,m≤2000)\)
然后有\(n\)行,每行\(m\)个字符,如果第\(i\)行的第\(j\)个字符是"R",那就说明点\((i,j)\)存在一块岩石,如果是".",那就说明点\((i,j)\)是空的
数据保证出发点\((1,1)\)一定是空的
输出格式##
输出一个整数,表示从\((1,1)\)走到\((n,m)\)的方案数对\(10^9+7\)取模的结果。
样例说明##
第一个样例中,不需要移动就能到达终点,所以只有一种路径方案,输出\(1\)
第二个样例中终点被岩石挡住了,无法到达,所以没有方案可以到达终点,输出\(0\)
点击本网址可以看到第三个样例的例图 https://assets.codeforces.com/rounds/1225/index.html
输入输出样例##
输入#1:#
1 1
.
输出#1:#
1
输入#2:#
2 3
...
..R
输出#2:#
0
输入#3#
4 4
...R
.RR.
.RR.
R...
输出#3:#
4
原题CF1225E
假如岩石不能移动,那么这就是一道\(dp\)裸题。
但是岩石的移动影响了原图,导致不能用\(dp\)转移。
由于只能向右或向下,通过画图分析我们知道当到达格\((x,y)\)的方向
与从\((x,y)\)转移的方向不同时,转移后到目标的所有路径是不受上一
步的影响,还是原图。
所以我们可以用\(dp\),在当前点向(到达这点的不同方向)用\(O(n或m)\)
的时间转移,可以优化到\(O(n^2(n+m))\)。
发现当前dp值是一段区间的dp值的和 (\(dp[i][j][0]=dp[i+1][j][1]+dp[i+2][j][1]...\)) ,所以用后缀和优化一下。
总的复杂度是\(O(nm)\)
代码实现:
#include<iostream>
#include<cmath>
#include<cstring>
#include<cstdio>
#include<ctime>
#include<climits>
#include<algorithm>
#define ll long long
using namespace std;
const int N=2010,mod=1e9+7;
int dp[N][N][2],sum[N][N][2],n,m,cnt[N][N][2]; //0 down 1 right
char ch[N][N];
int main()
{
int i,j,tmp;
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++) scanf("%s",ch[i]+1);
for(i=1;i<=n;i++) for(j=m;j>=1;j--) cnt[i][j][1]=cnt[i][j+1][1]+(ch[i][j]=='.');
for(j=1;j<=m;j++) for(i=n;i>=1;i--) cnt[i][j][0]=cnt[i+1][j][0]+(ch[i][j]=='.');
//预处理点(i,j)下可移动步数
if(ch[n][m]=='R') cout<<0,exit(0);
if(n==1 && m==1) cout<<1,exit(0);
dp[n][m][0]=dp[n][m][1]=1;
sum[n][m][0]=sum[n][m][1]=1;
//dp[i][j][0]表示(i,j)下一步是向下走
for(i=n;i>=1;i--)
{
for(j=m;j>=1;j--)
{
if(i==n && j==m) continue;
tmp=cnt[i+1][j][0];
dp[i][j][0]=(sum[i+1][j][1]-sum[i+tmp+1][j][1]+mod)%mod; //到达点(i,j)是从(i-1,j)转移过来的,所以取向右的后缀和
tmp=cnt[i][j+1][1];
dp[i][j][1]=(sum[i][j+1][0]-sum[i][j+tmp+1][0]+mod)%mod;
sum[i][j][0]=(sum[i][j+1][0]+dp[i][j][0])%mod; //更新后缀和
sum[i][j][1]=(sum[i+1][j][1]+dp[i][j][1])%mod;
}
}
cout<<(dp[1][1][0]+dp[1][1][1])%mod;
return ~~(0-0);
}
【CF1225E Rock Is Push】推岩石的更多相关文章
- CF1225E Rock Is Push (计数)
观察性质计数题orz小贺 考场上跟榜才切 我们只能往下和往右走,那么只有连续的往下和往右可能会造成不合法的情况!如果当前这一步是向右,那么只有它前面连续的一段向右可能影响到它. 考虑把连续的向右/下一 ...
- [CodeForces - 1225E]Rock Is Push 【dp】【前缀和】
[CodeForces - 1225E]Rock Is Push [dp][前缀和] 标签:题解 codeforces题解 dp 前缀和 题目描述 Time limit 2000 ms Memory ...
- 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 ...
- iPhone的Push(推送通知)功能原理浅析
第一部分:Push原理(以下绝大多数内容参考自.图片来自iPhone OS Reference Library)机制简介Push 的工作机制可以简单的概括为下图图中,Provider是指某个iPhon ...
- 58同城高性能移动Push推送平台架构演进之路
本文详细讲述58同城高性能移动Push推送平台架构演进的三个阶段,并介绍了什么是移动Push推送,为什么需要,原理和方案对比:移动Push推送第一阶段(单平台)架构如何设计:移动Push推送典型性能问 ...
- 转: 58同城高性能移动Push推送平台架构演进之路
转: http://geek.csdn.net/news/detail/58738 文/孙玄 本文详细讲述58同城高性能移动Push推送平台架构演进的三个阶段,并介绍了什么是移动Push推送,为什么需 ...
- 移动端Push推送
移动端Push推送 移动端开发逃不掉要做推送,这里给出服务端一种省时省力的解决方案. iOS:PushSharp.Apple.苹果有自己的推送服务,我们按照规则推送数据就好.这里我选取PushShar ...
- 浅谈push推送的一点感受
在手机已成为生活必不可分的一部分,push服务伴随而来.ios的apns,android随着谷歌退出中国市场,各家在android的推送不断展开.有厂商的推送,如小米.华为.魅族.oppo等,还有中间 ...
- push推送服务设计
PUSH系统架构设计简述 一.网络传输协议的选择 PUSH系统协议选取: UDP协议实时性更好,但是如何处理安全可靠的传输并且处理不同客户端之间的消息交互是个难题,实现起来过于复杂,那就非TCP协议莫 ...
随机推荐
- 封装:WPF中可以绑定的BindPassWord控件
原文:封装:WPF中可以绑定的BindPassWord控件 一.目的:本身自带的PassWord不支持绑定 二.Xaml部分 <UserControl x:Class="HeBianG ...
- kubernetes(k8s) Prometheus+grafana监控告警安装部署
主机数据收集 主机数据的采集是集群监控的基础:外部模块收集各个主机采集到的数据分析就能对整个集群完成监控和告警等功能.一般主机数据采集和对外提供数据使用cAdvisor 和node-exporter等 ...
- WebAPI中路由参数中包含字符-点“.”
请求url都是类似:/api/area/province.list 我们默认建立的Asp Net WebApi 服务时,如果请求url包含“.”,则返回404错误. 解决办法:需要在web.confi ...
- CMS-headless or non-headless, page-based or object-based storage?
内容管理系统对于很多在线教育企业来说都是至关重要的,他不仅可以用于内容的创作,编辑,发布,撤销,展示也可以用于运营或者市场产生他们需要的页面. 传统上,Wordpress是一个非常成功的CMS,他将内 ...
- python基础流程控制
流程控制主要分为三大类: 1.if 判断语句 2.while 循坏语句 3.for 循坏语句 下面以举例说明: if 判断语句: user1 = 'seven' user2 = 'alex' pass ...
- JavaScript 简单类型和复杂类型区别
一.基本类型 1.概述 值类型又叫做基本数据类型,简单数据类型.在存储时,变量中存储的是值本身,因此叫做值类型 2.基本类型在内存中的存储 基本数据类型存储在栈区中. 3.基本类型作为函数的参数 基本 ...
- 【译】itertools
1.Itertools模块迭代器的种类 1.1 无限迭代器: 迭代器 参数 结果 示例 count() start, [step] start, start+step, start+2*step, ...
- SparkStreaming之checkpoint检查点
一.简介 流应用程序必须保证7*24全天候运行,因此必须能够适应与程序逻辑无关的故障[例如:系统故障.JVM崩溃等].为了实现这一点,SparkStreaming需要将足够的信息保存到容错存储系统中, ...
- Hibernate 5.x 配置 C3P0 数据库连接池
Hibernate 5.x 配置 C3P0 连接池 首先准备好需要的 jar 包,这里我准备的是 Hibernate 5.2.10 版本: hibernate-core-5.2.10.Final.ja ...
- 《linux就该这么学》课堂笔记06 编写shell脚本、if、for
1.1.脚本的两种方式 交互式(Interactive):用户每输入一条命令就立即执行. 批处理(Batch):由用户事先编写好一个完整的Shell脚本,Shell会一次性执行脚本中诸多的命令. 1. ...