链接:https://www.nowcoder.com/acm/contest/139/A
来源:牛客网
Count the number of n x m matrices A satisfying the following condition modulo ().
* 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
*
* The number of test cases does not exceed .
题意 :
求有多少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)
套用上面的定理就变成了
#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;
}