牛客网暑期ACM多校训练营(第一场)A Monotonic Matrix [Lindström–Gessel–Viennot lemma]

                                         A Monotonic Matrix

学习一下Lindström–Gessel–Viennot lemma,有一个没听说过的数学,这数学场是要慢慢学习;

一种计算非交叉格子路径数的方法:

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

题目:在所有的n*m的矩阵中,数出满足条件的矩阵的数量(% 1e9+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.

考虑到01 和 12分界线

就是(n,0)到(0,m)的两条不相交(可重合)的路线;

平移其中一条,变成(n-1,-1)到(-1,m-1)

变成起点(n,0)和(n-1,-1),终点(0,m)和(-1,m-1)的严格不相交路径

套用公式就是C(n+m,n) ^ 2 - C(n+m,m-1)*C(n+m,n-1)

代码(补):

/*************************************************************************
	> File Name: a.cpp
	> Author:
	> Mail:
	> Created Time: 2018年07月20日 星期五 12时34分13秒
 ************************************************************************/

#include<bits/stdc++.h>
#define ll long long

using namespace std;
const int maxn = 3e3+7;
const ll mod = 1e9+7;

int n, m;
ll c[maxn][maxn];

void init()
{
    memset(c, 0, sizeof(c));
    for(int i = 1; i < maxn; i++) c[i][0] = 1, c[i][i] = 1;
    for(int i = 2; i < maxn; i++)
        for(int j = 1; j < i; j++)
            c[i][j] = (c[i-1][j-1] + c[i-1][j])%mod;
}


int main()
{
    init();
    //freopen("in.txt", "r", stdin);
    while(~scanf("%d%d", &n, &m))
    {
        printf("%lld\n", (c[n+m][n]*c[n+m][n]%mod - c[n+m][m-1]*c[n+m][n-1]%mod + mod)%mod);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_39792252/article/details/81130322