1. 程式人生 > >1011.盒子與球 SDNUOJ1011

1011.盒子與球 SDNUOJ1011

Description
現有r個互不相同的盒子和n個互不相同的球,要將這n個球放入r個盒子中,且不允許有空盒子。則有多少种放法?
Input
n, r(0 <= n, r <= 10)。
Output
有多少种放法。
Sample Input
3 2
Sample Output
6

第二類Stirling數實際上是集合的一個拆分,表示將n個不同的元素拆分成m個集合的方案數。描述為:將n個不同的球放入m個無差別的盒子中,要求盒子非空,有幾種方案?

遞推式
第二類Stirling數的推導和第一類Stirling數類似,可以從定義出發考慮第n+1個元素的情況,假設要把n+1個元素分成m個集合則分析如下:
(1)如果n個元素構成了m-1個集合,那麼第n+1個元素單獨構成一個集合。方案數 。
(2)如果n個元素已經構成了m個集合,將第n+1個元素插入到任意一個集合。方案數 m*S(n,m) 。
綜合兩種情況得:

#include <iostream>
using namespace std;

int fac(int n)
{
    int a = 1;
    while( n > 0 )
    {
        a *= n;
        n--;
    }
    return a;
}

int main()
{
    int m, n;
    long long f[11][11] = { 0 };
    cin >> m >> n;
    for(int i = 1; i <= n; i++)
        f[i][i]=1;
    for(int i = 1; i <= n; i++)
        for(int j = i + 1; j <= m; j++)
            f[i][j] = f[i - 1][j - 1] + i * f[i][j - 1];
    cout << fac(n) * f[n][m] << '\n';
    return 0;
}