【CF348D】Turtles(LGV引理)

点此看题面

  • 给定一张(n imes m)的网格图,其中有一些障碍格子。
  • 求有多少条从((1,1))((n,m))的路径,满足除起点和终点外不相交。
  • (n,mle3000)

(LGV)引理

一开始智障了,直接无脑套公式,求出((1,1))((n,m))的方案数(f_{n,m})然后认为答案就是:

[detegin{bmatrix}f_{n,m}&f_{n,m}\f_{n,m}&f_{n,m}end{bmatrix} ]

然后仔细一想不太对劲,众所周知二阶行列式(detegin{bmatrix}a&b\c&dend{bmatrix}=ad-bc),那么上面的式子算出来就是(0)

是公式出了问题?显然不是。

(LGV)引理要求的不相交是包括起点和终点的,起点和终点相同则肯定相交,因此方案数就是我们算出来的(0)

所以,我们要让它们开始先各走一步,最后各少走一步,也就是分别从((1,2))走到((n,m-1)),从((2,1))走到((n-1,m))

于是设(f1_{i,j},f2_{i,j})分别表示从((1,2),(2,1))走到((i,j))的方案数,转移的话如果当前格子是障碍就为(0),否则就是(f_{i,j-1}+f_{i-1,j})

最终答案就是(detegin{bmatrix}f1_{n-1,m}&f1_{n,m-1}\f2_{n-1,m}&f2_{n,m-1}end{bmatrix}),直接算就好了。

代码:(O(nm))

#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define Reg register
#define RI Reg int
#define Con const
#define CI Con int&
#define I inline
#define W while
#define N 3000
#define X 1000000007
using namespace std;
int n,m,f1[N+5][N+5],f2[N+5][N+5];char s[N+5][N+5];
int main()
{
	RI i,j;for(scanf("%d%d",&n,&m),i=1;i<=n;++i) scanf("%s",s[i]+1);
	for(i=1;i<=n;++i) for(j=1;j<=m;++j) s[i][j]^'#'&&//是障碍则方案数为0
		(f1[i][j]=i==1&&j==2?1:(f1[i-1][j]+f1[i][j-1])%X,f2[i][j]=i==2&&j==1?1:(f2[i-1][j]+f2[i][j-1])%X);//求出(1,2),(2,1)到每个格子的方案数
	return printf("%d
",(1LL*f1[n-1][m]*f2[n][m-1]-1LL*f1[n][m-1]*f2[n-1][m]%X+X)%X),0;//二阶行列式直接计算
}
败得义无反顾,弱得一无是处
原文地址:https://www.cnblogs.com/chenxiaoran666/p/CF348D.html