链接: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
#include
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((sqr(dp[n][m])+MOD-1LL*dp[m+1][n-1]*dp[m-1][n+1]%MOD))%MOD);
}
return 0;
}
上述代码中:static_casr
设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