CF348D LGV引理
题意:
给定一张图,图上存在障碍点,两个人从\((1,1)\)出发,只能向上或向右走,走到\((n,m)\)且路径不相交的方案数
数据范围:\(1\le n,m\le 3000\)
分析:
没什么好分析的,就是个裸题
前置芝士:LGV引理
\(LGV\)引理就是求解\(n\)组一一对应的起点到终点,且路径不相交的方案数
题目可以转化成2个起点:\((1,2),(2,1)\) 到 两个终点: \((n,m-1),(n-1,m)\)的不相交路径方案数,通过\(O(nm)\)的\(DP\)可以预处理出每个起点到每个终点的路径个数,构造出一个大小为\(2\times 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\n",((x1*x4%mod)-(x2*x3%mod)+mod)%mod);
}
}
int main()
{
zzc::work();
return 0;
}
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步