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\n", sum * a[n][r]);
    return 0;
}

 

转载于:https://www.cnblogs.com/RootVount/p/11418879.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值