题意:有一个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. wiki团队协作软件Confluence

    一.准备环境 准备环境 lamp(Linux.apache.mysql.php)框架 centos7 java jdk1.8.0_111 Distrib 5.5.52-MariaDB confluen ...

  2. Ubuntu 16.04 设置静态IP 注意事项

    目录 查看动态ip下的网络信息 查看默认网关 设置静态网络 查看动态ip下的网络信息 1 ifconifg # 查看网卡信息: 可以看出网口名称为 eno1, 以及子网掩码(mask) 查看默认网关 ...

  3. 复制/etc目录下所有以p开头,以非数字结尾的文件或目录到/tmp/mytest1目录中

    cp -r /etc/p*[a-Z] /tmp/mytest1

  4. 2019JAVA第一次編程总结

    2019第二周实验报告 Java实验报告 班级 计算机科学与技术二班 学号 20188442 姓名 吴怡君 完成时间 2019/9/7 评分等级 实验一 Java开发环境与简单Java程序 一. 实验 ...

  5. 【Linux-设备树】设备树

    Linux3.1之前的版本,对于一般的ARM平台的设备,板级信息一般存放在/arch/arm/mach-**目录下. 设备树对应的文件存放在/arch/arm/boot/dts/***.dts目录下 ...

  6. HTTP/2 最新漏洞,直指 Kubernetes!

    Java技术栈 www.javastack.cn 优秀的Java技术公众号 在这个数据.应用横行的时代,漏洞的出现早已屡见不鲜.在尚未造成大面积危害之前,我们该如何做好防御措施?或许从过往经常发生漏洞 ...

  7. 工作笔记20170315-------关于FAQ(Frequently Asked Questions)列表的代码

    源自于:http://www.17sucai.com/pins/3288.html (1)FAQ问答列表点击展开收缩文字列表 <ul>   <li class="clear ...

  8. solr集群搭建(SolrCloud)

    SolrCloud(solr 云)是 Solr 提供的分布式搜索方案,当你需要大规模,容错,索引量很大,搜索请求并发很高时可以使用SolrCloud.它是基于 Solr 和Zookeeper的分布式搜 ...

  9. vue.js(20)--vue路由

    后端路由 对于普通的网站,所有的超链接都是url地址,所有的url地址都对应着服务器上的资源 前端路由 对于单页面应用程序来说,主要通过单页面中的hash(#)来进行页面的切换.hash的特点是htt ...

  10. DRF之Jwt 实现自定义和DRF小组件及django-filter插件的使用

    一.DRF之Jwt 实现自定义 二.DRF(过滤,排序,分页)组件 三.Django-filter插件的使用和自定义 """ 1.drf-jwt手动签发与校验 :只是做t ...