题意:有一个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. Chapter03 第三节 浮点数

    3.3 浮点数 3.3.1 浮点数的表示 常规表示:12.34.0.01.8.0 E表示: 2.5e+8(2.5 10^8).7E6(7.0 10^6) (e大小写随意) (e+x或者E-x表示小数点 ...

  2. js五种不同的遍历 (filter, map,foreach,every, some,)

    var arr=[1,2,"a",2,4,1,4,"a",5,6,7,8,"aa","bb","c" ...

  3. 终于有人把 Docker 讲清楚了,万字详解!

    一.简介 1.了解Docker的前生LXC LXC为Linux Container的简写.可以提供轻量级的虚拟化,以便隔离进程和资源,而且不需要提供指令解释机制以及全虚拟化的其他复杂性.相当于C++中 ...

  4. W10: Warning: Changing a readonly file 解决办法

    在linux上编辑文件的时候,明明是使用的root登录的,可是这种至高无上的权限在按下i的时候被那串红色错误亵渎了W10: Warning: Changing a readonly file. 困扰两 ...

  5. Text Autosizer&&解决移动端网页文本字体怪异增大问题

    在做移动端页面时,有时你设置了字体大小,有的部分即使设置了行内样式也不生效,而有些显示正常,这个特性就是Text Autosizer在搞鬼. 以下是解决方案: ①给元素设置 -webkit-text- ...

  6. js实现404页面倒计时跳转

    <script type="text/javascript"> (function(){ var i=5,timer=null,number=document.getE ...

  7. git(github)配置密钥/私钥/SSH公钥)

    1.桌面右键 Git Bash Here 打开git命令行 2.ssh-keygen -t rsa -C "xxxxx@qq.com"(你的注册邮箱)enter 3.cd ~/.s ...

  8. modinfo - 显示当前内核模块信息

    总览 modinfo [ options ] <module_file> 描述 modinfo 工具软件用来对内核模块的目标文件 module_file 进行测试并打印输出相关信息. 选项 ...

  9. Thinking in Annotation

    Thinking in Java这本书很久前就购买了,打算有时间看一下,因为自己的时间被自己安排的紧张,也没时间看书.黄师傅上次课程讲到了注解的使用和反射的使用,今天打算学习一下注解.该文章参考Thi ...

  10. 面向对象原生js轮播图

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...