题意:有一个n*m的方格,每一格可能为空也可能有石头,要从(1,1)走到(n,m),每次可以往右或往下走

每次走的时候都会将自己面前的所有石头向移动方向推一格,如果碰到了边界就推不过去

问方案数模1e9+7

n,m<=2e3

思路:设dp[i][j][0/1]分别为当前走到(i,j),上一次从左/上走的合法方案数

合法的转移是行坐标或列坐标连续的一段,而且受障碍物个数和当前行/列号限制

写出式子之后可以发现决策范围对于i相同或者j相同是单调的,可以用队列维护,但显然二分更好写

 #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int,int> PII;
typedef pair<ll,ll> Pll;
typedef vector<int> VI;
typedef vector<PII> VII;
//typedef pair<ll,ll>P;
#define N 2010
//#define M 200010
#define INF 1e9
#define fi first
#define se second
#define MP make_pair
#define pb push_back
#define pi acos(-1)
#define mem(a,b) memset(a,b,sizeof(a))
#define rep(i,a,b) for(int i=(int)a;i<=(int)b;i++)
#define per(i,a,b) for(int i=(int)a;i>=(int)b;i--)
#define lowbit(x) x&(-x)
#define Rand (rand()*(1<<16)+rand())
#define id(x) ((x)<=B?(x):m-n/(x)+1)
#define ls p<<1
#define rs p<<1|1 const ll MOD=1e9+,inv2=(MOD+)/;
double eps=1e-;
int dx[]={-,,,};
int dy[]={,,-,}; char ch[N];
ll dp[N][N][],s[N][N][];
int b[N][N]; int read()
{
int v=,f=;
char c=getchar();
while(c<||<c) {if(c=='-') f=-; c=getchar();}
while(<=c&&c<=) v=(v<<)+v+v+c-,c=getchar();
return v*f;
} int calcb(int x1,int y1,int x2,int y2)
{
return b[x2][y2]-b[x1-][y2]-b[x2][y1-]+b[x1-][y1-];
} ll calc(int x1,int y1,int x2,int y2,int op)
{
ll res=s[x2][y2][op]-s[x1-][y2][op]-s[x2][y1-][op]+s[x1-][y1-][op];
res=(res%MOD+MOD)%MOD;
return res;
} void add(ll &a,ll b)
{
a+=b;
if(a>=MOD) a-=MOD;
if(a<) a+=MOD;
} int main()
{
int n=read(),m=read();
if(n==&&m==)
{
printf("1\n");
return ;
}
rep(i,,n)
{
scanf("%s",ch+);
rep(j,,m)
if(ch[j]=='R') b[i][j]=;
}
rep(i,,n)
rep(j,,m) b[i][j]=b[i-][j]+b[i][j-]-b[i-][j-]+b[i][j];
dp[][][]=dp[][][]=;
s[][][]=s[][][]=;
rep(len,,n+m)
{
rep(i,,len-)
{
int j=len-i;
if(i>n||j>m) continue;
int l=,r=j-,last=j;
while(l<=r)
{
int mid=(l+r)>>;
if(calcb(i,mid+,i,m)<=m-j){last=mid; r=mid-;}
else l=mid+;
}
if(last<j) add(dp[i][j][],calc(i,last,i,j-,));
add(s[i][j][],s[i-][j][]);
add(s[i][j][],s[i][j-][]);
add(s[i][j][],-s[i-][j-][]);
add(s[i][j][],dp[i][j][]); l=,r=i-,last=i;
while(l<=r)
{
int mid=(l+r)>>;
if(calcb(mid+,j,n,j)<=n-i){last=mid; r=mid-;}
else l=mid+;
}
if(last<i) add(dp[i][j][],calc(last,j,i-,j,));
add(s[i][j][],s[i-][j][]);
add(s[i][j][],s[i][j-][]);
add(s[i][j][],-s[i-][j-][]);
add(s[i][j][],dp[i][j][]);
} }
ll ans=(dp[n][m][]+dp[n][m][])%MOD;
printf("%I64d\n",ans);
return ;
}

【CF1247E】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 - 1225E]Rock Is Push 【dp】【前缀和】

    [CodeForces - 1225E]Rock Is Push [dp][前缀和] 标签:题解 codeforces题解 dp 前缀和 题目描述 Time limit 2000 ms Memory ...

  3. HDU 3433 (DP + 二分) A Task Process

    题意: 有n个员工,每个员工完成一件A任务和一件B任务的时间给出,问要完成x件A任务y件B任务所需的最短时间是多少 思路: DP + 二分我也是第一次见到,这个我只能说太难想了,根本想不到. dp[i ...

  4. 两种解法-树形dp+二分+单调队列(或RMQ)-hdu-4123-Bob’s Race

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4123 题目大意: 给一棵树,n个节点,每条边有个权值,从每个点i出发有个不经过自己走过的点的最远距离 ...

  5. POJ-2533最长上升子序列(DP+二分)(优化版)

    Longest Ordered Subsequence Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 41944   Acc ...

  6. hdu2993之斜率dp+二分查找

    MAX Average Problem Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Othe ...

  7. poj3208 Apocalypse Someday 数位dp+二分 求第K(K <= 5*107)个有连续3个6的数。

    /** 题目:poj3208 Apocalypse Someday 链接:http://poj.org/problem?id=3208 题意:求第K(K <= 5*107)个有连续3个6的数. ...

  8. hdu 1025:Constructing Roads In JGShining's Kingdom(DP + 二分优化)

    Constructing Roads In JGShining's Kingdom Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65 ...

  9. 【bzoj3312】[Usaco2013 Nov]No Change 状态压缩dp+二分

    题目描述 Farmer John is at the market to purchase supplies for his farm. He has in his pocket K coins (1 ...

  10. [Codeforces 865C]Gotta Go Fast(期望dp+二分答案)

    [Codeforces 865C]Gotta Go Fast(期望dp+二分答案) 题面 一个游戏一共有n个关卡,对于第i关,用a[i]时间通过的概率为p[i],用b[i]通过的时间为1-p[i],每 ...

随机推荐

  1. maven项目的导包问题,已经加载jar包了可是idea检测不到

    1.详细请参考 https://blog.csdn.net/brainhang/article/details/76725080 把测试模式注释即可

  2. jeecg项目将workbook 的Excel流添加到zip压缩包里导出

    1.直接献出代码 Map<String,List<ConfidentialInformation>> typeMap = new HashMap<>(); try ...

  3. Git 的使用及其一些基本用法

    打开你的git-bash 绑定用户和邮箱作为标识 $ git config --global user.name "your name" $ git config --global ...

  4. xmake v2.2.2, 让C/C++拥有包依赖自动构建

    前言 历经四个多月,xmake终于更新了新版本v2.2.2,并且上线了重量级功能:原生支持的远程依赖包管理. 而这个特性,其实我陆陆续续写了将近一年的时间,才初步完成,对于此特性的开发进展和历史,有兴 ...

  5. [LeetCode] 45. 跳跃游戏 II

    题目链接 : https://leetcode-cn.com/problems/jump-game-ii/ 题目描述: 给定一个非负整数数组,你最初位于数组的第一个位置. 数组中的每个元素代表你在该位 ...

  6. 小白学Python(19): Pyinstaller 生成 exe 文件

    python 默认并不包含 PyInstaller 模块,因此需要自行安装 PyInstaller 模块. 安装 PyInstaller 模块与安装其他 Python 模块一样,使用 pip 命令安装 ...

  7. Min-Max 容斥的证明

    这里有 Min-Max 容斥的证明以及唯一一道博主做过的例题... 上个结论: \[Min\{S\}=\sum_{T\subseteq S,T\not=\varnothing}(-1)^{|T|-1} ...

  8. 02.AutoMapper 之扁平化(Flattening)

    https://www.jianshu.com/p/65099590c930   扁平化(Flattening) 对象映射器的常见用法是将一个复杂对象模型扁平化为一个简单模型.例如您有一个以下复杂模型 ...

  9. 浏览器常用12种兼容问题(JS)

    //1.滚动条到顶端的距离(滚动高度) var scrollTop = document.documentElement.scrollTop || document.body.scrollTop; / ...

  10. spring controller 方法测试

    controller 测试 不使用其他api接口测试工具 一般而言,我们写好一个模块后,会对其进行单元测试,再集成到现有的系统中. 但是呢~针对Controller.Service.Dao三层来说,我 ...