#LGV引理,DP#CF348D Turtles

题目

一张 \(n\)\(m\) 列的网格图,图中的有些格子上面有障碍物,但保证 \((1,1)\)\((n,m)\) 上面都没有障碍物。

\((1,1)\) 处有两只乌龟,都想要去 \((n,m)\)。乌龟每次都可以向下或者向右走一格,前提是格子上没有任何障碍物。

要求两只乌龟在前往 \((n,m)\) 的路途中不可以相遇,即除了起点和终点,他们的路径没有其他公共点。

求出从起点到终点的不同路径对数。答案对 \(10^9+7\) 取模。


分析

这两只乌龟一只会从 \((2,1)\) 走到 \((n-1,m)\),另一只会从 \((1,2)\) 走到 \((n,m-1)\)

根据 LGV 引理,不相交的路径数就是行列式的值,也就是

\(\begin{vmatrix} (2,1)\to (n-1,m) & (2,1)\to (n,m-1)\\ (1,2)\to (n-1,m) & (1,2)\to (n,m-1) \end{vmatrix}\)

这个用 Dp 求解再把答案合并即可


代码

#include <iostream>
#include <algorithm>
using namespace std;
const int N=3011,mod=1000000007; typedef long long lll;
lll dp[N][N],Ans0,Ans1,Ans2,Ans3; char S[N][N]; int n,m;
void Dp(int lx,int ly,int rx,int ry,lll &Ans){
    dp[lx][ly]=S[lx][ly]=='.';
    for (int i=lx;i<=rx;++i)
    for (int j=ly;j<=ry;++j) if (S[i][j]=='.')
        dp[i][j]=(dp[i][j]+dp[i-1][j]+dp[i][j-1])%mod;
    Ans=dp[rx][ry];
    for (int i=lx;i<=rx;++i)
    for (int j=ly;j<=ry;++j) dp[i][j]=0;
}
int main(){
    ios::sync_with_stdio(0);
    cin.tie(0),cout.tie(0);
    cin>>n>>m;
    for (int i=1;i<=n;++i) cin>>(S[i]+1);
    Dp(1,2,n,m-1,Ans0),Dp(1,2,n-1,m,Ans1);
    Dp(2,1,n,m-1,Ans2),Dp(2,1,n-1,m,Ans3);
    cout<<((Ans1*Ans2-Ans0*Ans3)%mod+mod)%mod;
	return 0;
}
posted @ 2025-09-06 14:42  lemondinosaur  阅读(5)  评论(0)    收藏  举报