杨氏矩阵 and 钩子公式
杨氏矩阵
-
满足杨氏矩阵条件
- 如果(i,j)没有元素,则它右边和上边的相邻格子也一定没有元素
- 如果(i,j)有元素,则它右边和上边的相邻元素要么没有元素,要么有元素且比(i,j)大
-
1~n所组成的杨氏矩阵的个数可以通过下面的递推式得到:
F ( 1 ) = 1 , F ( 2 ) = 2 F(1)=1,F(2)=2 F(1)=1,F(2)=2
F ( n ) = F ( n − 1 ) + ( n − 1 ) F ( n − 2 ) , ( n > 2 ) F(n)=F(n-1)+(n-1)F(n-2),\ (n>2) F(n)=F(n−1)+(n−1)F(n−2), (n>2)
钩子公式:
-
钩子长度:某一格子右边的格子数和它上边的格子数之和
-
对于给定形状的杨氏矩阵,不同的杨氏矩阵个数 c n t cnt cnt 为:
c n t = n ! g [ 1 ] g [ 2 ] . . . g [ n ] cnt=\frac{n!}{g[1]g[2]...g[n]} cnt=g[1]g[2]...g[n]n!
g [ n ] g[n] g[n] 表示第n个格子的钩子长度+1
例题:2279 – Mr. Young’s Picture Permutations (poj.org)
- 有一个小处理,这题是一个倒置的杨氏矩阵,所以处理的时候也要倒置处理
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
#include<vector>
#include<stack>
#include<bitset>
#include<cstdlib>
#include<cmath>
#include<set>
#include<list>
#include<deque>
#include<map>
#include<queue>
using namespace std;
typedef long long ll;
const int N=205;
int g[N], a[N];
ll gcd(ll a,ll b) { return b?gcd(b,a%b):a; }
signed main()
{
ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
int k;
while(cin>>k && k)
{
for(int i=1;i<=k;i++) cin>>a[i];
int tot=0;
for(int i=k;i>=1;i--)
{
for(int j=1;j<=a[i];j++)
{
g[++tot]=a[i]-j+1;
for(int q=i+1;q<=k;q++)
{
if(a[q]>=j) g[tot]++;
else break;
}
}
}
ll x=1,y=1;
for(int i=tot;i>=1;i--)
{
x*=i; y*=g[i];
int d=gcd(x,y);
x/=d; y/=d;
}
cout<<x<<endl;
}
return 0;
}