poj 2779 Mr. Young's Picture Permutations

本文介绍了一道关于学生拍照排列的问题,采用钩子公式解决。问题要求在行列递减约束条件下,计算不同身高学生的排列总数。文章提供了C++实现代码,并详细解释了钩子公式的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

浪费我好多时间啊,如果dp实力强的,可以用dp写,确实算是dp的好题,但是我很水,只能去找那个钩子公式,baidu、google都找了,结果只找到英文的原网站(不吐槽,我这种英语水平怎么可能看懂),最后终于看见一篇还可以的,大致的应用会了,大家如果问我证明,我也只能说sorry。

英文原网站:http://en.wikipedia.org/wiki/Young_tableau

题意:杨先生要给他的学生们拍照片,若第i行站了a[i]个人,则有a[1] ≥ a[2] ≥ ... ≥ a[n],所有的行都是靠左对齐的。并且,在同一行和同一列里面,从左到右或者从上到下身高都是递减的。现在所有学生的身高都不相同,学生数不超过30个,行数不超过5。你需要求出所有可能的排队方法的总数。

思路:别人说这种问题是钩子公式的模板问题。我来简单的说说钩子公式吧,把学生站队的地方看成一个地图,

最后的总数(sum)为 sum=n! /((H1)*(H2)*....*(Hn)),学生总数为n,对地图上的每个学生进行一个进行一个编号1~n,Hx表示第x个学生同一列(下面的)和同一排(右边的)的学生加上他自己的人数总和,这个编号是对结果无影响的,所以只需要算Hx就ok。

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;

int gcd(int a,int b)
{
    return  a%b==0?b:(gcd(b,a%b)) ;
}

int n,map[14][41],val[51],fact[41],sum;
int main(void)
{
    while(cin>>n,n)
    {
        sum = 0;
        memset(map,0,sizeof(map));
        for(int i=1;i<=n;++i)
        {
            int a;
            scanf("%d",&a);
            sum += a;
            for(int j=1;j<=a;++j)
            {
                map[i][j] = 1;
            }
        }
        int cou = 1;
        for(int i=1;i<14;++i)
        for(int j=1;j<41;++j)
        if(map[i][j])
        {
          val[cou] = 1;
          for(int k=i+1;k<14;++k)
                val[cou] += map[k][j];
          for(int k=j+1;k<41;++k)
                val[cou] += map[i][k];
          ++cou;
        }
        for(int i=1;i<=sum;++i)
            fact[i] = i;
        for(int i=1;i<=sum;++i)
            for(int j=1;j<=sum;++j)
        {
            int tmp = gcd(fact[i],val[j]);
            fact[i] /= tmp; val[j] /= tmp;
        }
        long long num = 1;
        for(int i=1;i<=sum;++i)
            num *= fact[i];
        cout<<num<<endl;
    }


    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值