• 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;
    }
    
  • 相关阅读:
    LCM与GCD算法
    LCS,LIS,LICS算法
    高精度算法(C/C++)
    SystemTap
    VMware15下解决Ubuntu18.04没有网络连接问题
    Git ssh-key 配置问题
    Ubuntu18.04更换国内源
    sql 错误日志存储路径设置
    资源
    System.Data.DataTable 基本方法
  • 原文地址:https://www.cnblogs.com/violetholmes/p/15330444.html
Copyright © 2020-2023  润新知