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

Count the number of n x m matrices A satisfying the following condition modulo (109+7).

*Ai,j ∈{0,1,2}forall1≤i≤n,1≤j≤m.
*Ai,j ≤Ai+1,j forall1≤i<n,1≤j≤m.
*Ai,j ≤Ai,j+1 forall1≤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 ≤ n, m ≤ 103
* The number of test cases does not exceed 10 5.

示例1:

输入
12
22
1000 1000

输出

6
20
540949876

题意:

让你得出有多少个矩阵。这个矩阵从左到右,从上到下,都是不递减的。

POINT:

 

考虑 01 和 12 的分界线
是 (n, 0) 到 (0, m) 的两条不相交(可重合)路径
平移其中一条变成 (n-1, -1) 到 (-1, m-1)
变成起点 (n, 0) 和 (n-1, -1),终点 (0, m) 和 (-1, m-1) 的严格不相交路径 套 Lindström–Gessel–Viennot lemma

答案是Cn+m,n2 -Cn+m,m-1Cn+m,n-1

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

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

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

#include <stdio.h>
#include <iostream>
#include <string.h>
using namespace std;
#define LL long long
LL dp[2050][2050];
const LL mod = 1e9+7;
 
void init()
{
    dp[0][1]=dp[1][1]=1;
    for(int i=2;i<=2000;i++){
        dp[0][i]=dp[i][i]=1;
        for(int j=1;j<i;j++){
            dp[j][i]=(dp[j][i-1]+dp[j-1][i-1])%mod;
        }
    }
}
 
 
 
int main()
{
    init();
    int n,m;
    while(~scanf("%d%d",&n,&m)){
        printf("%lld\n",(dp[n][m+n]*dp[n][m+n]%mod+mod-dp[n-1][n+m]*dp[m-1][n+m]%mod)%mod);
    }
 
}

猜你喜欢

转载自blog.csdn.net/mr_treeeee/article/details/81130466