杨氏矩阵与钩子公式

转载 2015年07月07日 22:06:44

杨氏矩阵又叫杨氏图表,它是这样一个矩阵,满足条件:

 

(1)如果格子(i,j)没有元素,则它右边和上边的相邻格子也一定没有元素。

(2)如果格子(i,j)有元素a[i][j],则它右边和上边的相邻格子要么没有元素,要么有元素且比a[i][j]大。

 

1 ~ n所组成杨氏矩阵的个数可以通过下面的递推式得到:

 

 

如图就是n=3时的杨氏矩阵。

 

 

 

 

下面介绍一个公式,那就是著名的钩子公式

 

对于给定形状,不同的杨氏矩阵的个数为:n!除以每个格子的钩子长度加1的积。其中钩子长度定义为该格子

右边的格子数和它上边的格子数之和。

 

题目:http://poj.org/problem?id=1825

 

 

介绍完了钩子公式,那么我们可以来做一道基础题了。

 

题目:给四行,第一行放5个数字,第二行放三个数字,第三行放3个数字,第四行放1个数字,都是左对齐的排列,

     现有1~12共12个数字,要求放到这四行中,从上到下,从左到右都是按小到大排列,问你共有几种排法?


() () () () ()

() () ()

() () ()

()

 

这个问题直接利用钩子公式解决即可。

 

 

杨氏矩阵既可以用来当堆,又可以当成平衡树。通常杨氏矩阵会涉及到两个问题:

 

(1)在杨氏矩阵中查找值为x的元素      (2)在杨氏矩阵中找第K大的元素

 

对于第一个问题,其实有两种方法,第一种方法就是二分查找法,这种方法的时间效率不是很好。第二种方法就是类

堆查找法。方法是这样的:从矩阵的右上角出发,对于元素a[i][j],如果a[i][j]==x,则找到元素x,直接返

回; 如果a[i][j]> x,则向下移动,即继续比较a[i+1][j]与x;如果a[i][j] < x,则向左移动,即继续比

较a[i][j-1]与x。该算法的时间复杂度是O(m+n)。

bool Find(int a[][N],int n,int m,int x)
{
    assert(a != NULL && n > 0 && m > 0);
    int row = 0;
    int col = m - 1;
    while(row <= n - 1 && col >= 0)
    {
        if(a[row][col] == x) return true;
        else if(a[row][col] > x) col--;
        else row++;
    }
    return false;
}


 

对于第二个问题,首先,二分枚举找到一个数x,它比杨氏矩阵中k个数大;然后,利用类堆查找法找到刚好小于x的

元素。该算法的时间复杂度为O((m+n)log(mn)),但不需要额外存储空间。

int get_order(int a[][N],int n,int m,int k)
{
    int row = 0;
    int col = m - 1;
    int order = 0;
    while(row <= n - 1 && col >= 0)
    {
        if(a[row][col] < k)
        {
            order += col + 1;
            row++;
        }
        else col--;
    }
    return order;
}

int Find_Kth_Num(int a[][N],int n,int m,int k)
{
    int low = a[0][0];
    int high = a[n-1][m-1];
    int order = 0;
    int mid = 0;
    do
    {
        mid = (low + high) >> 1;
        order = get_order(a,n,m,mid);
        if(order == k) break;
        else if(order > k) high = mid - 1;
        else low = mid + 1;
    }while(1);
    int row = 0;
    int col = m - 1;
    int ret = mid;
    while(row <= n - 1 && col >= 0)
    {
        if(a[row][col] < mid)
        {
            ret = max(ret,a[row][col]);
            row++;
        }
        else col--;
    }
    return ret;
}


版权声明:本文为博主原创文章,未经博主允许不得转载。

POJ 2279 Mr. Young's Picture Permutations(杨氏矩阵和钩子公式)

Mr. Young's Picture Permutations Time Limit: 1000MS Memory Limit: 65536K Total Su...

杨氏矩阵与钩子公式

杨氏矩阵又叫杨氏图表,它是这样一个矩阵,满足条件:   (1)如果格子(i,j)没有元素,则它右边和上边的相邻格子也一定没有元素。 (2)如果格子(i,j)有元素a[i][j],则它右边和上边的相邻格...

【POJ2279】【杨氏矩阵/钩子公式】Mr. Young's Picture Permutations

杨氏矩阵/钩子公式+数学
  • sdfzchy
  • sdfzchy
  • 2017年07月10日 10:44
  • 158

杨氏矩阵-young tableau 算法分析+实现

简介:young tableau 是一个很奇特的数据结构,它的性质是堆和BST(二叉查找树)的结合,对于查找它的效率优于堆,对于删除和插入它比BST更方便。 young tableau是一个m*n的矩...
  • zzran
  • zzran
  • 2013年01月08日 18:06
  • 2574

第二十三、四章:杨氏矩阵查找,倒排索引关键词Hash不重复编码实践

第二十三、四章:杨氏矩阵查找,倒排索引关键词Hash不重复编码实践 作者:July、yansha。编程艺术室出品。 出处:结构之法算法之道。 前言   ...

杨氏矩阵 中查找一个数字是否存在,时间复杂度小于O(N)

#include int FIND_NUMBER(int arr[3][3],int key) { int i = 0,j = 2;//使数据从对角线的左上开始比较。 while(i=0) { ...

剑指offer之数组的调整及在杨氏矩阵中的查找

1.调整数组使奇数全部都位于偶数前面。 题目:输入一个整数数组,实现一个函数,来调整该数组中数字的顺序使得数组中所有的奇数位于数组的前半部分,所有偶数位于数组的后半部分。 首先分析一下:看到这样一个...

杨氏矩阵找第N大(小)的O(N)线性算法

杨氏矩阵:一个N*N的矩阵,它的每行每列都单调递增(或者宽松一些,单调不减),即a[i][j] 遇到的两道面试题: 1. 输出杨氏矩阵中最小的N个数。 2. 两个升序数组A和B,长度都是N。...
  • taoqick
  • taoqick
  • 2014年04月09日 13:54
  • 1387

杨氏矩阵的查找

题目描述 杨氏矩阵,即在一个二维数组中,每一行都按照从左到右严格递增的顺序排序,每一列都按照从上到下严格递增的顺序排序。请完成一个函数,输入这样的一个N*N的二维数组和M个整数,判断数组中是否含有上...

查找----二维数组的查找之杨氏矩阵

原帖在此;http://blog.csdn.net/michealmeng555/article/details/2489923 算法研讨的论文【原创分享】 杨氏矩阵 Young Tableau ...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:杨氏矩阵与钩子公式
举报原因:
原因补充:

(最多只允许输入30个字)