CF348D Solution

题解

易得,两条路径一定分别通过\((1,2)\)\((n-1,m)\)\((2,1)\)\((n,m-1)\)的路径。因此可以算出\((1,2)→(n-1,m)\)\((2,1)→(n,m-1)\)的方案数,将它们相乘,但这样会多余计算在中间有交点的情况。因为\((1,2)→(n,m-1)\)\((2,1)→(n-1,m)\)的路径一定相交,所以它们方案数之积就等于中间有交点的情况数,减去即可。

代码

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=3010,mod=1e9+7;
char a[N][N];
int c1[N][N],c2[N][N];
inline int read()
{
	int s=0,w=1; char ch=getchar();
	while(ch<'0' || ch>'9') {if(ch=='-') w=-1; ch=getchar();}
	while(ch>='0' && ch<='9') s=s*10+ch-'0',ch=getchar();
	return s*w;
}
signed main()
{
	int n=read(),m=read();
	for(int i=1;i<=n;i++) scanf("%s",a[i]+1);
	if(a[1][2]=='#' || a[2][1]=='#' || a[n][m-1]=='#' || a[n-1][m]=='#') {printf("0"); return 0;}
	c1[1][2]=1;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			if(a[i][j]!='#' && !c1[i][j]) c1[i][j]=(c1[i-1][j]+c1[i][j-1])%mod;
	c2[2][1]=1;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			if(a[i][j]!='#' && !c2[i][j]) c2[i][j]=(c2[i-1][j]+c2[i][j-1])%mod;
	printf("%lld",(c1[n-1][m]*c2[n][m-1]%mod-c1[n][m-1]*c2[n-1][m]%mod+mod)%mod);
	return 0;
}
posted @ 2021-09-24 15:00  violet_holmes  阅读(27)  评论(0编辑  收藏  举报