• HDOJ 4372 第一类斯特林数


    链接:

    http://acm.split.hdu.edu.cn/showproblem.php?pid=4372

    题意:

    有一系列的楼房,高度从1~n,然后从左侧看能看到f个楼房,右侧看能看到b个楼房,问有多少个方案数满足。

    题解:

    首先我们知道一个结论: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];

    代码:

    31 ll stir[MAXN][MAXN];
    32 ll C[MAXN][MAXN];
    33 
    34 void init() {
    35     stir[1][0] = 0;
    36     stir[1][1] = 1;
    37     rep(i, 2, MAXN) rep(j, 1, i + 1)
    38         stir[i][j] = (stir[i - 1][j - 1] + (i - 1)*stir[i - 1][j]) % MOD;
    39     rep(i, 1, MAXN) {
    40         C[i][0] = C[i][i] = 1;
    41         rep(j, 1, i) C[i][j] = (C[i - 1][j] + C[i - 1][j - 1]) % MOD;
    42     }
    43 }
    44 
    45 int main() {
    46     ios::sync_with_stdio(false), cin.tie(0);
    47     init();
    48     int T;
    49     cin >> T;
    50     while (T--) {
    51         int n, f, b;
    52         cin >> n >> f >> b;
    53         cout << C[f + b - 2][f - 1] * stir[n - 1][f + b - 2] % MOD << endl;
    54     }
    55     return 0;
    56 }
  • 相关阅读:
    2017-09-13
    JavaSE07——异常
    FastDFS入门、搭建以及应用(转载)
    Centos7安装JDK1.8
    「扫盲」 Elasticsearch(转载)
    Java06——面向对象
    Java05——数组
    Java02——基础
    spring boot 配置文件配置项 数字特殊处理问题
    java动态代理机制之自定义实现动态代理
  • 原文地址:https://www.cnblogs.com/baocong/p/7622237.html
Copyright © 2020-2023  润新知