1. 程式人生 > >NOIP 衝刺:常見的遞推之第二類斯特林數

NOIP 衝刺:常見的遞推之第二類斯特林數

第二類斯特林數
例題:
給定n 個有標號的球,標號依次為1,2,…,n。將這n個球放入r 個相同的盒子裡,不允許有空盒,問有多少种放置方法。
例如把4個球放入2個盒子有7種方法,這7 種不同的放置方法依次為:
{(1),(234)}, {(2),(134)},
{(3),(124)}, {(4),(123)},
{(12),(34)}, {(13),(24)},{(14),(23)}。

我們設一個狀態:f[i][j] 代表把i個球放入j個盒子裡(盒子不空)的總計方案數,那麼,對於每一個球,我們都有兩種情況:
1.新開一個盒子 那麼f[i][j]=f[i-1][j-1]
2.不新開一個盒子 那麼可以把他放入每一個盒子中,所以f[i][j]=f[i-1][j]*j

所以轉移方程為f[i][j]=f[i-1][j]*j+f[i-1][j-1];
所以沒了,f[n][r] 即為所求
注意邊界條件 f[i][i]=1; f[i][0]=0;

#include <cstdio>
#include <iostream>
using namespace std;
int n,r;
long long f[50][50];//把i個蛋放入j個框中的方案數 
int main(){
    scanf("%d%d",&n,&r);
    f[1][1]=1;
    f[0][0]=0;//這個好像是第二類斯特林數
    for
(int i=1;i<=n;i++){ f[i][i]=1; f[i][0]=0; } for(int i=2;i<=n;i++){ for(int j=1;j<=r;j++){ f[i][j]=f[i-1][j]*j+f[i-1][j-1]; } } cout<<f[n][r]; return 0; }