A Monotonic Matrix(第一场)

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

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 524288K,其他语言1048576K
64bit IO Format: %lld

题目描述

Count the number of n x m matrices A satisfying the following condition modulo (109+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 ≤ n, m ≤ 103
* The number of test cases does not exceed 105.

题解:考虑 0101 和 1212 的分界线,用 (n,0)(n,0) 到 (0,m)(0,m) 的两条不相交(可重合)路径,平移其中一条变成 (n−1,−1)(n−1,−1) 到 (−1,m−1)(−1,m−1) 变成起点 (n,0)(n,0) 和 (n−1,−1)(n−1,−1),终点 (0,m)(0,m) 和 (−1,m−1)(−1,m−1) 的严格不相交路径,套 Lindstrom-Gessel-Viennot lemma 定理。

https://en.wikipedia.org/wiki/Lindstr%C3%B6m%E2%80%93Gessel%E2%80%93Viennot_lemma#References

代码:

#include<cstdio>
#include<iostream>
using namespace std;
const int MOD=1e9+7;
void update(int& x,int y)
{
	x+=y;
	if(x>=MOD)
	x-=MOD;
}
int sqr(int x)
{
	return x*1LL*x%MOD; 
}
	int dp[1005][1005];
int main()
{

	dp[0][0]=1;
	for(int i=0;i<=1002;i++)
	{
		for(int j=0;j<=1002;j++)
		{
			if(i)
			{
				update(dp[i][j],dp[i-1][j]);
			}
			if(j)
			{
				update(dp[i][j],dp[i][j-1]);
			}
		}
	}
	int m,n;
	while(scanf("%d%d",&n,&m) == 2)
	{
		printf("%d\n",static_cast<int>((sqr(dp[n][m])+MOD-1LL*dp[m+1][n-1]*dp[m-1][n+1]%MOD))%MOD);
	}
return 0;
}

上述代码中:static_casr<int >(m),是指将m转换成int类型;m*1LL是将m转换成longlong类型的。

设n=2,m=2.  sqr(dp[2][2])+MOD-1LL*dp[2+1][2-1]*dp[2-1][2+1]%MOD))%MOD=6*6-4*4=20

dp数组:1 1 1  1 

                1 2 3  4

                1 3 6  10

                1 4 10 20

  

猜你喜欢

转载自blog.csdn.net/d1183/article/details/81129521