标签:cnt sum 岩石 Rock Push include CF1225E dp mod
题目描述你现在在一个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)(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
----------------------------------------------------------------------------------------------------------------------------------------
假如岩石不能移动,那么这就是一道bfs裸题。
但是岩石的移动影响了原图,导致不能用bfs向外扩展。
由于只能向右或向下,通过画图分析我们知道当到达格(x,y)的方向
与从(x,y)转移的方向不同时,转移后到目标的所有路径是不受上一
步的影响,还是原图。
所以我们可以用bfs,在当前点向(到达这点的不同方向)用O(n或m)
的时间转移,记忆化一下可以优化到O(n^2(n+m))。
发现当前dp值是一段区间的dp值的和,所以用后缀和优化一下。
总的复杂度是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]=='.'); 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; 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; 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); }View Code
标签:cnt,sum,岩石,Rock,Push,include,CF1225E,dp,mod 来源: https://www.cnblogs.com/lhc-yyl-lyx-lyh/p/11762890.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。