zoukankan      html  css  js  c++  java
  • HDU4372(第一类斯特林数)

    题意:N座高楼,高度均不同且为1~N中的数,从前向后看能看到F个,从后向前看能看到B个,问有多少种可能的排列数。

    0 < N, F, B <= 2000

    首先我们知道一个结论:n的环排列的个数与n-1个元素的排列的个数相等,因为P(n,n)/n=(n-1)!。

    可以肯定,无论从最左边还是从最右边看,最高的那个楼一定是可以看到的.

    假设最高的楼的位置固定,最高楼的编号为n,那么我们为了满足条件,可以在楼n的左边分x-1组,右边分y-1组,且用每

    组最高的那个元素代表这一组,那么楼n的左边,从左到右,组与组之间最高的元素一定是单调递增的,且每组中的最高元

    素一定排在该组的最左边,每组中的其它元素可以任意排列(相当于这个组中所有元素的环排列)。右边反之亦然。

    然后,可以这样考虑这个问题,最高的那个楼左边一定有x-1个组,右边一定有y-1个组,且每组是一个环排列,这就引出

    了第一类Stirling数(n个人分成k组,每组内再按特定顺序围圈的分组方法的数目)。

    我们可以先把n-1个元素分成x-1+y-1组,然后每组内部做环排列。再在所有组中选取x-1组放到楼n的左边。所以答案是

    ans(n, f, b) = C[f + b - 2][f - 1] * S[n - 1][f + b - 2];

    #include <iostream>
    #include <string.h>
    #include <stdio.h>
    
    using namespace std;
    typedef long long LL;
    
    const int N=2005;
    const LL MOD=1000000007;
    
    LL C[N][N];
    LL S[N][N];
    
    void Init()
    {
    int i,j;
    for(i=0;i<N;i++)
    {
    C[i][0]=1;
    C[i][i]=1;
    S[i][0]=0;
    S[i][i]=1;
    for(j=1;j<i;j++)
    {
    C[i][j]=(C[i-1][j]%MOD+C[i-1][j-1]%MOD)%MOD;
    S[i][j]=((i-1)%MOD*S[i-1][j]%MOD+S[i-1][j-1]%MOD);
    }
    }
    }
    
    int main()
    {
    LL t,n,f,b,ans;
    Init();
    scanf("%I64d",&t);
    while(t--)
    {
    scanf("%I64d%I64d%I64d",&n,&f,&b);
    ans=C[f+b-2][f-1]%MOD*S[n-1][f+b-2]%MOD;
    printf("%I64d
    ",ans);
    }
    return 0;
    }
    原文链接:https://blog.csdn.net/ACdreamers/article/details/9732431
    

      

  • 相关阅读:
    利息基础理论
    本地数据库
    线上一个数组查询遇到的坑
    老兵的十年职场之路(二)
    老司机心得之时间管理"入坑"
    补习系列(19)-springboot JPA + PostGreSQL
    PostGreSQL(1)-源码安装
    补习系列(18)-springboot H2 迷你数据库
    SpringBoot 2 要不要升级
    补习系列(17)-springboot mongodb 内嵌数据库
  • 原文地址:https://www.cnblogs.com/cutemush/p/11908349.html
Copyright © 2011-2022 走看看