盒子與球解題報告

題目描述: ios

Description 函數

現有r個互不相同的盒子和n個互不相同的球,要將這n個球放入r個盒子中,且不容許有空盒子。問有多少種方法?
例如:有2個不一樣的盒子(分別編爲1號和2號)和3個不一樣的球(分別編爲一、二、3號),則有6種不一樣的方法:
spa

Input code

兩個整數,n和r,中間用空格分隔。(0≤n, r≤10) ip

Output 數學

僅一行,一個整數(保證在長整型範圍內)。表示n個球放入r個盒子的方法。 it

Sample Input io

3 2

Sample Output stream

6
思路:一道數學問題,與求包含n個元素的集合劃分爲正好k個非空不相交子集的方法的數目十分類似,因此用Stirling數來解決,
遞推公式爲:
S(n,k)=0; (n<k||k=0) 
S(n,n) = S(n,1) = 1,
S(n,k) = S(n-1,k-1) + kS(n-1,k).
固然這道題還有一點不一樣之處就是每一個盒子又有區別,因此到最後求出Stirling數後,還要乘上k(盒子數)的全排列。
如下爲記憶化搜索和遞推兩種思路的源代碼:
記憶化搜索源程序:
#include <iostream>
#include <cstdio>
using namespace std;
int n,k,sum=0;
void init()
{
  scanf("%d %d",&n,&k);
}
int work(int n,int k)
{
  if(k>n)
	return(0);
  else if(k==1||k==n)
	return(1);
  else return(work(n-1,k-1)+work(n-1,k)*k);
}
int jiecheng(int k)
{
  int i;
  int zong=1;
  for(i=k;i>0;i--)
    zong*=i;
  return(zong);
}
void solve()
{
  if(k==1)
	  printf("%d",1);
  else if(k==n)
    printf("%d",jiecheng(k));
  else if(k>n)
    printf("%d",0);
  else if(k==0)
    printf("%d",0); //中間加了好多特殊狀況判斷,感受有點沒有必要~~
  else   
  {
	  sum=work(n,k);
    printf("%d",sum*jiecheng(k));
  }
}
int main()
{
  init();
  solve();
}
 
遞推源代碼:
#include <iostream>
#include <cstdio>
using namespace std;
int a[11][11];
int n,k;
void init()
{
  freopen("1257.in","r",stdin);
  scanf("%d %d",&n,&k);
  a[0][0]=1;
}
int jiecheng(int k)
{
  int i;
  int zong=1;
  for(i=k;i>0;i--)
    zong*=i;
  return(zong);
}
void solve()
{
  int i,j;
  for(i=1;i<=k;i++)
    for(j=1;j<=n;j++)
      a[j][i]=a[j-1][i-1]+(a[j-1][i]*i);
  freopen("1257.out","w",stdout);
  printf("%d",a[n][k]*jiecheng(k));
}
int main()
{
  init();
  solve(); 
}
反思:沒有什麼註釋的,只要細心便可。

斯特林數

斯特林數出如今許多組合枚舉問題中. 對第一類斯特林數 StirlingS1[n,m], 給出恰包含 m 個圈的 n 個元素 的排列數目. 斯特林數知足母函數關係 . 注意某些 的定義與 Mathematica 中的不一樣,差異在於因子 . 第二類斯特林數 StirlingS2[n,m]給出把 n 個可區分小球分配到m個不可區分的的盒子,且盒子沒有空盒子的方法的數量. 它們知足關係 . 劃分函數 PartitionsP[n]給出把整數 n 寫爲正整數的和,不考慮順序的方法的數目. PartitionsQ[n]給出把整數 n 寫爲正整數的和,而且和中的整數是互不相同的 寫法的數目
設S(p,k)是斯特林數
S(p,k)的一個組合學解釋是:將p個物體劃分紅k個非空的不可辨別的(能夠理解爲盒子沒有編號)集合的方法數。
S(p,k)的遞推公式是:
 S(p,k) = k*S(p-1,k) + S(p-1,k-1) ,1<= k <=p-1
邊界條件:
S(p,p) = 1 ,p>=0
S(p,0) = 0 ,p>=1
遞推關係的說明:考慮第p個物品,p能夠單獨構成一個非空集合,此時前p-1個物品構成k-1個非空的不可辨別的集合,方法數爲S(p-1,k-1);也能夠前p-1種物品構成k個非空的不可辨別的集合,第p個物品放入任意一箇中,這樣有k*S(p-1,k)種方法。
第一類斯特林數和第二類斯特林數有相同的初始條件,但遞推關係不一樣。引用Brualdi《組合數學》裏的一段註釋 「對於熟悉線性代數的讀者,解釋以下:具備(好比)實係數,最多爲p次的那些各項式造成一個p+1維的向量空間。組1,n,n^2,...。n^p和組 A(n, 0),A(n,1),A(n,2),... ,A(n,p)都是該空間的基。第一類Stirling數和第二類Stirling數告訴咱們如何用其中的一組基表示另外一組基。」
相關文章
相關標籤/搜索