cf rock is push 【dp】
附上学习的博客:https://blog.csdn.net/u013534123/article/details/102762673
大致题意:一个迷宫,里面有很多箱子,你可以向右或者向下走。当你遇到一个或者多个箱子的时候,你可以把箱子往你移动的方向推动,但是不能把箱子推出到墙壁外面。你从左上角出发,问你有多少种方法到右下角。
考虑如果没有箱子,那么就是一个很简单的递推问题,对于一个格子,要么从上面要么从左边来。有箱子的话,由于箱子可以被推动而且不能推到外面,所以我们要考虑是否可以从上面或者下面过来。
还是一样考虑dp,令dp[i][j][0]表示走到位置(i,j)且最后一步是从左边过来的方案,同理dp[i][j][1]表示最后一步从上面来的方案数。然后转移的话,考虑如果是从上面来,我们可以枚举最后一次向右走的位置k,即从(k,j)到(i,j)是一直往下走。如此我们只需要判断是否可以走过来,也即判断(k,j)往下的石头数目是否大于(i,j)下方的格子数,如果大于,那么说明是可以走到(i,j)的,那么把方案数dp[k][j][0]。同理可以得出从左边来,方案数就是dp[i][k][1]。于是有转移方程:


x和y分别表示最前的一个位置,且从这个位置开始到那一行或者那一列的最后的石头数目小于等于后面允许放石头的格子数目。x和y可以用二分比较快速的求,然后显然可以用前缀和来优化,于是复杂度就是O(N^2logN)。然后,仔细想想可以发现x和y是有单调性的,于是可以进一步优化到O(N^2),但是考虑到并没有这个必要而且会复杂一点所以我就没有写了。具体见代码:
——————以上是博客的解法
我另外补充下:
#include<bits/stdc++.h>
#define fi first
#define se second
#define LL long long
#define pb push_back
#define INF 0x3f3f3f3f
#define sc(x) scanf("%d",&x)
#define scc(x,y) scanf("%d%d",&x,&y)
#define sccc(x,y,z) scanf("%d%d%d",&x,&y,&z)
using namespace std; const int N = 2010;
const int mod = 1e9 + 7; int dp[N][N][2],sum[N][N][2],R[N][N][2];
char s[N][N]; int main()
{
int n,m;
scc(n,m);
if(n==1&&m==1)
{
puts("1");
return 0;
}
for(int i=0;i<n;i++)
{
scanf("%s",s[i]);
for(int j=0;s[i][j];j++)
if (s[i][j]=='R') R[i][j][0]=R[i][j][1]=1;
}
for(int i=0;i<n;i++)
for(int j=1;j<m;j++)
R[i][j][0]+=R[i][j-1][0];//前缀和表示到列到该点的石头
for(int i=0;i<m;i++)
for(int j=1;j<n;j++)
R[j][i][1]+=R[j-1][i][1];
sum[0][0][0]=sum[0][0][0]=1;
dp[0][0][0]=dp[0][0][1]=1;
for(int i=1;i<n;i++)
{
if (R[n-1][0][1]<=n-i-1) //因为石头只能推到边不能出界,例如该列五个格子有两个格子有石头,那你肯定有效格数到3这一个嘛
dp[i][0][1]+=dp[i-1][0][1];
sum[i][0][0]=dp[i][0][1];//为什么sum的第三维是0呢?请看上图公式
}
for(int i=1;i<m;i++)
{
if (R[0][m-1][0]<=m-i-1)
dp[0][i][0]+=dp[0][i-1][0];
sum[0][i][1]=dp[0][i][0];
}
for(int i=1;i<n;i++)
for(int j=1;j<m;j++)
{
int l=0,r=i-1,mid,t,res=-1;
while(l<=r)//二分找找到第某行,该行小于等于后面允许放石头的格子数目
{
mid=l+r>>1;
t=R[n-1][j][1]-R[mid][j][1];
if (t<=n-i-1) res=mid,r=mid-1;
else l=mid+1;
}
if(res>=0)
{
int tmp=res==0?0:sum[res-1][j][1];
dp[i][j][1]=(sum[i-1][j][1]-tmp+mod)%mod;//前缀和基操,
}
sum[i][jd][0]=(sum[i][j-1][0]+dp[i][j][1])%mod;
l=0,r=j-1,res=-1;
while(l<=r)
{
mid=l+r>>1;
t=R[i][m-1][0]-R[i][mid][0];
if (t<=m-j-1) res=mid,r=mid-1;
else l=mid+1;
}
if (res>=0)
{
int tmp=res==0?0:sum[i][res-1][0];
dp[i][j][0]=(sum[i][j-1][0]-tmp+mod)%mod;
}
sum[i][j][1]=(sum[i-1][j][1]+dp[i][j][0])%mod;
}
printf("%d\n",(dp[n-1][m-1][0]+dp[n-1][m-1][1])%mod);
}
cf rock is push 【dp】的更多相关文章
- [CodeForces - 1225E]Rock Is Push 【dp】【前缀和】
[CodeForces - 1225E]Rock Is Push [dp][前缀和] 标签:题解 codeforces题解 dp 前缀和 题目描述 Time limit 2000 ms Memory ...
- Kattis - honey【DP】
Kattis - honey[DP] 题意 有一只蜜蜂,在它的蜂房当中,蜂房是正六边形的,然后它要出去,但是它只能走N步,第N步的时候要回到起点,给出N, 求方案总数 思路 用DP 因为N == 14 ...
- HDOJ 1423 Greatest Common Increasing Subsequence 【DP】【最长公共上升子序列】
HDOJ 1423 Greatest Common Increasing Subsequence [DP][最长公共上升子序列] Time Limit: 2000/1000 MS (Java/Othe ...
- HDOJ 1501 Zipper 【DP】【DFS+剪枝】
HDOJ 1501 Zipper [DP][DFS+剪枝] Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Ja ...
- HDOJ 1257 最少拦截系统 【DP】
HDOJ 1257 最少拦截系统 [DP] Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Other ...
- HDOJ 1159 Common Subsequence【DP】
HDOJ 1159 Common Subsequence[DP] Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K ...
- HDOJ_1087_Super Jumping! Jumping! Jumping! 【DP】
HDOJ_1087_Super Jumping! Jumping! Jumping! [DP] Time Limit: 2000/1000 MS (Java/Others) Memory Limit: ...
- POJ_2533 Longest Ordered Subsequence【DP】【最长上升子序列】
POJ_2533 Longest Ordered Subsequence[DP][最长递增子序列] Longest Ordered Subsequence Time Limit: 2000MS Mem ...
- HackerRank - common-child【DP】
HackerRank - common-child[DP] 题意 给出两串长度相等的字符串,找出他们的最长公共子序列e 思路 字符串版的LCS AC代码 #include <iostream&g ...
随机推荐
- Koa 本地搭建 HTTPS 环境
openssl 首先本地需要安装 openssl,用于生成自签名证书. $ brew install openssl 检查安装: $ openssl version LibreSSL 2.6.5 生成 ...
- C# copy source directory files with original folder to the destination path
private static void PathCopyFilesWithOriginalFolder() { ; try { string sourceDir = @"E:\Source& ...
- Java学习 1.1——(JVM介绍)Java为什么能够跨平台?
首先介绍一下Java的各个层级,先放一张图: 硬件,操作系统和操作系统接口:这三级不说大家都知道,操作系统有很多种,比如Windows,Linux.Windows又分为win7,win10,win x ...
- springboot~yml里的自定义配置~续
之前写了关于读取自定义配置的文章springboot~yml里的自定义配置,而今天主要说一下对复杂配置信息的读取方法,我们简单的配置用@Value注解就可以了,而结构复杂的一般使用@Configura ...
- form表单input回车提交问题
问题:文本框输入完成后点击回车页面刷新问题出在form上,当表单中只有一个文本框的时候获取焦点并点击回车之后会提交表单内容,就会发生刷新事件. 解决方法: 1.增加一个隐藏的输入框 <input ...
- Electron npm install 常见错误(Windows)
问题一:node_gyp使用版本不对 if not defined npm_config_node_gyp (node "C:\Users\Administrator\AppData\Roa ...
- vue-better-scroll实现移动端下拉加载组件
1.下载安装better-scroll npm i -S better-scroll 1.1安装完成之后,打开pacaage.json文件查看,是否有(better-scroll) "dep ...
- Os-HackNos-Report
实验主机:Os-hackerNos靶机一台/Kali linux攻击机一台 实验网络:桥接网络 实验目标:获取靶机的Root权限 难易程度:简单 前期工作: 1:下载Virtualbox虚拟化软件(也 ...
- 第420期 Python 周刊
文章.教程或讲座 Python 数据科学教程:分析 Stack Overflow 2019 年开发者调查表** https://www.youtube.com/watch?v=_P7X8tMplsw ...
- 在ASP.NET中备份数据库以及还原(不成熟)
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threa ...