盒子与球

来源:互联网 发布:icmp.dll被java嗲用 编辑:程序博客网 时间:2024/05/01 04:37

 

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

Output

有多少种放法。

Sample Input

3 2

Sample Output

6

 

 分析:
    这一题在不考虑编号的情况下可以简单的抽象为
把包含n个元素的集合划分为正好r个非空不相交子集,即第二类stirling数。设s[i][j],表示前i个球放在前j个盒子里的方案数,然后分两种情况讨论:
    1、第i个小球单独放在第j个盒子里,则此情况方案数为s[i-1][j-1];
    2、第i个小球放在前j个盒子里,则此种情况方案数为s[i-1][j]*j;
 因此s[i][j]=s[i-1][j-1]+s[i-1][j]*j;
在这之后,我们可不能忘了一点,
第二类stirling数是将n个有区别的球的球放入r个无标号的盒子中( n>=k>=1,且盒子不允许为空)的方案数,而此题的盒子有编号,所以我们必须将递推得出的结果s[n][r]再乘上r!,这才是最终的结果。

 

 

#include<iostream>
using namespace std;
long long s[20][20] = {1},jc[11]={0,1,2,6,24,120,720,5040,40320,36288,3628800};
int main()
{
    int n,r;
    cin>>n>>r;
    long long an = 1;
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= r; j++)
        {
            s[i][j] = j * s[i - 1][j] + s[i - 1][j - 1];
        }
    cout<<s[n][r] * jc[r]<<endl;
    return 0;
}

0 0
原创粉丝点击