zoukankan      html  css  js  c++  java
  • 【杨氏定理+钩子公式】初步

    首先,我们来看一个最简单的问题:

    我在学校门口卖奶茶,奶茶一元一杯。今天下午开门的时候,我发现找零的钱忘带了。

    这时候来了 2n 个人,其中 n 个人身上只有一张一元钱,另外 n 个人身上只有一张两元钱。我就让他们排成一队,然后用这 n 个人的一元钱来找给付两元的人。当然,排队的时候得保证每次来一个付两元的人的时候都有的找。

    假设所有拿一元的人和拿两元的人都没有分别,我现在想知道,他们有多少种排队方式?

    这个问题的答案大家都知道,是 Cat[n],即第 n 个卡特兰数(Catalan number)。不过我现在的问题是如下的升级问题。

    升级1:条件同上,但这时候来的人数为 3n ,其中 n 个人只有一张一元钱,n 个只有一张两元钱, n 个只有一张三元钱(假设题设的每种面值的钞票均存在)。我仍然让他们排成一队,只要有付两元的就用一元找,付三元的就用两元找。同样得保证每当需要找钱时有对应的钱可以找。求他们有多少种排队方式?

    以及最终问题

    升级2:条件同上,但这时候来的人数为 mn,其中拥有面值为一元至 m 元的人均有 n 个。每当支付 k (1<kleq m)元时用 k-1 面值的钞票去找零。求合法排队方式数。

     

    先看例题:【HihoCoder1480:矩阵填数 】

    题意:将N*M个整数填入N*M的矩阵中,要求当前位置的数小于左边和上面的数,求方案数。

    有【钩子公式】:

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

     则易得此题公式:

    ans=fac[n*m];
    for(int i=1;i<=n;i++) 
        for(int j=1;j<=m;j++){
           ans=ans*rev[i+j-1]%Mod;    
    }

     

    【关键】:这个矩阵填数和卖奶茶的关系:

    加入3*N个人买奶茶: N个一块钱的+N个两块钱+N个三块钱,给他们的排队队伍编号1,2,3 ...  3*N。然后把这3*N个人拿去填充矩阵。

    具体的,一块钱的在第一排,两块钱的在第二排,三块钱的在第三排。 那么他们必须满足:先来的在左边,小面额的在上边。

    即当前位置是数小于上面的和左边的。这样以来这个解就可以用钩子定理来求解了。

     

    此外:

    杨氏矩阵还有递推公式:f[n]=f[n-1]+(n-1)*f[n-2]。

    还可以用卡特兰数表示:第(n-1)*(m-1)+1个卡特兰数。

     

     

  • 相关阅读:
    C语言I博客作业04
    C语言II博客作业03
    C语言II博客作业02
    C语言II博客作业01
    学期总结
    C语言I博客作业08
    C语言I博客作业07
    C语言I博客作业06
    C语言I博客作业05
    C语言I博客作业04
  • 原文地址:https://www.cnblogs.com/hua-dong/p/8454215.html
Copyright © 2011-2022 走看看