题意:
给定一张图,图上存在障碍点,两个人从((1,1))出发,只能向上或向右走,走到((n,m))且路径不相交的方案数
数据范围:(1le n,mle 3000)
分析:
没什么好分析的,就是个裸题
前置芝士:LGV引理
(LGV)引理就是求解(n)组一一对应的起点到终点,且路径不相交的方案数
题目可以转化成2个起点:((1,2),(2,1)) 到 两个终点: ((n,m-1),(n-1,m))的不相交路径方案数,通过(O(nm))的(DP)可以预处理出每个起点到每个终点的路径个数,构造出一个大小为(2 imes 2) 的 (LGV)引理矩阵,然后直接求矩阵的行列式就可以了
代码:
#include<bits/stdc++.h>
using namespace std;
namespace zzc
{
const int maxn = 3005;
const long long mod = 1e9+7;
long long f[maxn][maxn],x1,x2,x3,x4;
bool mp[maxn][maxn];
char ch[maxn];
long long n,m;
void work()
{
scanf("%lld%lld",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%s",ch+1);
for(int j=1;j<=m;j++)
{
if(ch[j]=='#')mp[i][j]=true;
}
}
memset(f,0,sizeof(f));
f[1][1]=1;
for(int i=2;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(mp[i][j]) continue;
f[i][j]=(f[i][j]+f[i-1][j]+f[i][j-1])%mod;
}
}
x1=f[n][m-1];x2=f[n-1][m];
memset(f,0,sizeof(f));
f[1][1]=1;
for(int i=1;i<=n;i++)
{
for(int j=2;j<=m;j++)
{
if(mp[i][j]) continue;
f[i][j]=(f[i][j]+f[i-1][j]+f[i][j-1])%mod;
}
}
x3=f[n][m-1];x4=f[n-1][m];
printf("%lld
",((x1*x4%mod)-(x2*x3%mod)+mod)%mod);
}
}
int main()
{
zzc::work();
return 0;
}