• SDNU 1011.盒子与球(斯特林函数)


    Description

    现有r个互不相同的盒子和n个互不相同的球,要将这n个球放入r个盒子中,且不允许有空盒子。则有多少种放法?

    Input

    n, r(0 <= n, r <= 10)。

    Output

    有多少种放法。

    Sample Input

    3 2

    Sample Output

    6

    Source

     
    思路:这道题用的是斯特林函数。
    第一类斯特林函数:将 n 个不同元素构成m个圆排列,如果要将n + 1个元素构成m个圆排列,考虑第n + 1个元素:
                                (1)如果n个元素构成m - 1个圆排列,则第n + 1个元素独自构成一个圆排列:s(n, m - 1);
                                (2)如果n个元素构成m个圆排列,则第n + 1个元素插入任意元素的左边:n * s(n, m);
                                  总和s(n + 1, m) = s(n, m - 1) + n * s(n, m)。
    第二类斯特林函数:将n个不同的球放入m个无差别的盒子中,要求盒子非空,考虑第n + 1个元素:
                                (1)如果n个元素构成m - 1个集合,则第n + 1个元素就构成单独一个集合:s(n, m - 1);
                                (2)如果n个元素构成m个集合,则第n + 1个元素就查到任意一个集合:m * s(n, m);
                                  总和s(n + 1, m) = s(n, m - 1) + m * s(n, m)。
     
    但是题目要求是r个不同的盒子,r个不同盒子的排列就是 r!,所以最后的答案应该乘以r的阶乘。
    #include<bits/stdc++.h>
    using namespace std;
    
    #define ll long long
    #define eps 1e-9
    
    const int inf = 0x3f3f3f3f;
    const int mod = 1e9+7;
    const int maxn = 100000 + 8;
    
    int a[18][18];
    
    int main()
    {
        int n, r, sum = 1;
        memset(a, 0, sizeof(a));
        scanf("%d%d", &n, &r);
        a[1][1] = 1;
        for(int i = 2; i <= n; i++)
        {
            for(int j = 1; j <= r; j++)
            {
                a[i][j] = a[i - 1][j - 1] + a[i - 1][j] * j;
            }
        }
        for(int i = 1; i <= r; i++)
            sum *= i;
        printf("%d
    ", sum * a[n][r]);
        return 0;
    }
  • 相关阅读:
    比较全的笔记
    ios路线
    字符串颜色
    ios 开发学习步骤
    百度地图反地理
    p12证书
    ios官方demo
    ios视频网盘
    图片穿透
    OC温习一:基本数据类型
  • 原文地址:https://www.cnblogs.com/RootVount/p/11418879.html
Copyright © 2020-2023  润新知