【hihcoder 1480】矩阵填数

1.题目链接。小Hi在玩一个游戏,他需要把1, 2, 3, ... NM填入一个N行M列的矩阵中,使得矩阵每一行从左到右、每一列从上到下都是递增的。  

2.这是杨氏矩阵的一个性质,其实这个题目的本质就是在求1-nm这nm个数字,可以构造出多少个n*m杨氏矩阵。

首先对于杨氏矩阵,n个数,可以构成的杨氏矩阵的数量,在不加形状限制的情况下:可以从递推公式得到。

F[i]代表i个数构成的杨氏矩阵的数量,F[1]=1,F[2]=2,F[n]=F[n-1]+(n-1)(F[n-2]).(这个递推很眼熟????)。但是对于给定形状的杨氏矩阵,数量可以通过钩子定理计算:对于给定形状,不同的杨氏矩阵的个数为:n!/(每个格子的钩子长度加1的积)。
其中钩子长度定义为该格子右边的格子数和它上边的格子数之和。

然后这个题就没了,主要是知道了一下杨氏矩阵和钩子定理。

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const ll mod = 1e9 + 7;
ll qpow(ll a, ll b)
{
	ll res = 1;
	while (b)
	{
		if (b&1)res = res * a % mod;
		a = a * a % mod;
		b >>= 1;
	}
	return res;
}
int main()
{
	int n, m;
	while (~scanf("%d%d", &n, &m))
	{
		ll ans = 1;
		for (int i = 2; i <= n * m; i++)ans = ans * i % mod;
		for (int i = 1; i <= n; i++)
		{
			for (int j = 1; j <= m; j++)
			{
				ll num = n + m - i - j + 1;
				ll inv = qpow(num, mod - 2);
				ans = ans * inv % mod;
			}
		}
		cout << ans << endl;
	}
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值