牛客网暑期ACM多校训练营(第一场)A Monotonic Matrix

链接:https://www.nowcoder.com/acm/contest/139/A
来源:牛客网
 

题目描述

Count the number of n x m matrices A satisfying the following condition modulo (10^9+7).
* Ai, j ∈ {0, 1, 2} for all 1 ≤ i ≤ n, 1 ≤ j ≤ m.
* Ai, j ≤ Ai + 1, j for all 1 ≤ i < n, 1 ≤ j ≤ m.
* Ai, j ≤ Ai, j + 1 for all 1 ≤ i ≤ n, 1 ≤ j < m.

输入描述:

The input consists of several test cases and is terminated by end-of-file.
Each test case contains two integers n and m.

输出描述:

For each test case, print an integer which denotes the result.

示例1

输入

1 2
2 2
1000 1000

输出

6
20
540949876

备注:

 

*  1\leq n,m\leq10^3
* The number of test cases does not exceed 10^{5}.

 

题意 :

求有多少n*m的矩阵满足:

1.每个数都是0或1或2

2.a(i,j)<=a(i+1,j)

3.a(i,j)<=a(i,j+1)

 

题解:

Lindström–Gessel–Viennot lemma

对于一张无边权的DAG图,给定n个起点和对应的n个终点,这n条不相交路径的方案数为

det() (该矩阵的行列式)

其中e(a,b)为图上a到b的方案数

摘自大牛博客

 

考虑01的分界线和12的分界线

就是两条可以相交的路径

那么题目就可以转化为求从(n,0)到(0,m)的两条可相交路径的方案数

上面的定理是求不相交路径

我们可以把一个起点平移到(n+1,1)

对应的终点平移到(1,m+1)

套用上面的定理就变成了

C(n+m,n)*C(n+m,n)-C(n+m,n-1)*C(n+m,n+1)

 

#include
#include
#include
#include
using namespace std;
typedef long long ll;
const ll mod=1e9+7;
ll quick(ll a,ll k){
	ll ans=1;
	while(k){
		if(k&1)ans=ans*a%mod;
		k/=2;
		a=a*a%mod;
	}
	return ans;
}
ll fac[2005];
ll C(ll n,ll m){
	return fac[n]*quick(fac[n-m],mod-2)%mod*quick(fac[m],mod-2)%mod;
}
void init(){
	fac[0]=fac[1]=1;
	for(ll i=2;i<=2000;i++)fac[i]=fac[i-1]*i%mod;
}
int main(){
	ll n,m,i,j;
	init();
	while(scanf("%lld%lld",&n,&m)!=EOF){
		ll ans=C(n+m,n)*C(n+m,n)-C(n+m,n-1)*C(n+m,n+1);
		ans=(ans%mod+mod)%mod;
		printf("%lld\n",ans);
	}
	return 0;
}

 

你可能感兴趣的:(数学)