问题描述:有n个球,放进k个盒子,有多少种不同的放法?(球必须全部放在盒子中,不能丢弃)
球可能相同,也可能不同,盒子亦然。另外,盒子可能限定可为空,也可能限定不可为空。这样就有8种可能:
情况 | 球是否相同 | 盒子是否相同 | 盒子能否为空 | 答案 | 计算时间复杂度 |
---|
1 | T | T | F |
d
(
n
,
k
)
=
D
(
n
−
k
,
k
)
d(n,k)=D(n-k,k)
d(n,k)=D(n−k,k) |
O
(
(
n
−
k
)
k
)
O((n-k)k)
O((n−k)k) |
2 | T | T | T |
∑
i
=
1
k
d
(
n
,
i
)
=
D
(
n
,
k
)
\sum_{i=1}^kd(n,i)=D(n,k)
∑i=1kd(n,i)=D(n,k) |
O
(
n
k
)
O(nk)
O(nk) |
3 | F | T | F |
S
(
n
,
k
)
S(n,k)
S(n,k) |
O
(
n
k
)
O(nk)
O(nk) |
4 | F | T | T |
∑
i
=
1
k
S
(
n
,
i
)
\sum_{i=1}^kS(n,i)
∑i=1kS(n,i) |
O
(
n
k
)
O(nk)
O(nk) |
5 | T | F | F |
C
n
−
1
k
−
1
C_{n-1}^{k-1}
Cn−1k−1 | 最快
O
(
n
−
k
)
O(n-k)
O(n−k) 精度较高
O
(
n
k
)
O(nk)
O(nk) |
6 | T | F | T |
C
n
+
k
−
1
k
−
1
C_{n+k-1}^{k-1}
Cn+k−1k−1 | 最快
O
(
n
)
O(n)
O(n) 精度较高
O
(
(
n
+
k
)
k
)
O((n+k)k)
O((n+k)k) |
7 | F | F | F |
k
!
∗
S
(
n
,
k
)
k!*S(n,k)
k!∗S(n,k) | 斯特林数法:
O
(
n
k
)
O(nk)
O(nk) 容斥原理:
O
(
k
l
o
g
n
)
O(klogn)
O(klogn) |
8 | F | F | T |
k
n
k^n
kn | 快速幂:
O
(
l
o
g
n
)
O(logn)
O(logn) |
符号注释
1、
C
n
k
C_n^k
Cnk:组合数,
C
n
k
=
n
!
k
!
(
n
−
k
)
!
C_n^k=\frac{n!}{k!(n-k)!}
Cnk=k!(n−k)!n!
2、
d
(
n
,
k
)
d(n,k)
d(n,k):划分数,将正整数n划分为k个其它正整数(正整数,当然不能为0)的划分方法数。递推公式:
d
(
n
,
k
)
=
∑
i
=
1
m
d
(
n
−
k
,
i
)
,
m
=
m
i
n
{
m
−
n
,
n
}
d(n,k)=\sum_{i=1}^md(n-k,i),\ \ m=min\{m-n,n\}
d(n,k)=∑i=1md(n−k,i), m=min{m−n,n}。特别地,
d
(
n
,
1
)
=
d
(
n
,
n
)
=
1
d(n,1)=d(n,n)=1
d(n,1)=d(n,n)=1,如果
k
>
n
k>n
k>n则
d
(
n
,
k
)
=
0
d(n,k)=0
d(n,k)=0。
3、
S
(
n
,
k
)
S(n,k)
S(n,k):第二类斯特林数,将n个不同元素划分为k个非空集合的划分方法数。递推公式:
S
(
n
,
k
)
=
S
(
n
−
1
,
k
−
1
)
+
k
∗
S
(
n
−
1
,
k
)
S(n,k)=S(n-1,k-1)+k*S(n-1,k)
S(n,k)=S(n−1,k−1)+k∗S(n−1,k)。
4、总划分数
D
(
n
,
k
)
D(n,k)
D(n,k)是指将正整数n划分为不超过k个正整数的划分总数。显然,
D
(
n
,
k
)
=
∑
i
=
1
k
d
(
n
,
i
)
D(n,k)=\sum_{i=1}^kd(n,i)
D(n,k)=∑i=1kd(n,i)。特别地,如果
k
>
n
k>n
k>n,则
D
(
n
,
k
)
=
D
(
n
,
n
)
D(n,k)=D(n,n)
D(n,k)=D(n,n)。但有一个更快的计算方法:由划分数的递推公式可得:
D
(
n
,
k
)
−
D
(
n
,
k
−
1
)
=
D
(
n
−
k
,
k
)
D(n,k)-D(n,k-1)=D(n-k,k)
D(n,k)−D(n,k−1)=D(n−k,k),也就是
D
(
n
,
k
)
=
D
(
n
−
k
,
k
)
+
D
(
n
,
k
−
1
)
D(n,k)=D(n-k,k)+D(n,k-1)
D(n,k)=D(n−k,k)+D(n,k−1)。这样,计算
D
(
n
,
k
)
D(n,k)
D(n,k)就可以在
O
(
n
k
)
O(nk)
O(nk)的时间内完成。又
d
(
n
,
k
)
=
D
(
n
,
k
)
−
D
(
n
,
k
−
1
)
=
D
(
n
−
k
,
k
)
d(n,k)=D(n,k)-D(n,k-1)=D(n-k,k)
d(n,k)=D(n,k)−D(n,k−1)=D(n−k,k),则
d
(
n
,
k
)
d(n,k)
d(n,k)的计算可以在
O
(
(
n
−
k
)
k
)
O((n-k)k)
O((n−k)k)时间内完成。
各种情况详解
1、这个明显就是划分数。划分数的推导:由于每个盒子都不能为空,所以至少能放k个球。假设一个合法的划分已完成,此时从每个盒子中拿出一个球,还剩
n
−
k
n-k
n−k个球。如果没有空盒子,相当于把
n
−
k
n-k
n−k个球划分成k部分,这样合法的划分有
d
(
n
−
k
,
k
)
d(n-k,k)
d(n−k,k)种;如果有一个空盒子,相当于
n
−
k
n-k
n−k个球划分为
k
−
1
k-1
k−1部分,情况有
d
(
n
−
k
,
k
−
1
)
d(n-k,k-1)
d(n−k,k−1)种,以此类推,可得递推公式。
2、与1同理。另外一种思考角度:考虑
D
(
n
,
k
)
D(n,k)
D(n,k),如果至少一个盒子不放球,就有
D
(
n
,
k
−
1
)
D(n,k-1)
D(n,k−1)种方法;如果所有盒子都放球,那么从每个盒子中拿出一个球,剩余
n
−
k
n-k
n−k个球,相当于把这
n
−
k
n-k
n−k个球放到k个盒子中,
D
(
n
−
k
,
k
)
D(n-k,k)
D(n−k,k)。可得递推公式
D
(
n
,
k
)
=
D
(
n
,
k
−
1
)
+
D
(
n
−
k
,
k
)
D(n,k)=D(n,k-1)+D(n-k,k)
D(n,k)=D(n,k−1)+D(n−k,k)。
3、刚好符合第二类斯特林数的定义。第二类斯特林数的推导:考虑前n-1个元素的划分结果。现在要把第n个元素插进去。如果前n-1个元素已经形成
k
k
k个集合,则可以将第n个元素放入任意一个集合中,
k
S
(
n
−
1
,
k
)
kS(n-1,k)
kS(n−1,k)。如果前n-1个元素已经形成
k
−
1
k-1
k−1个集合,则必须将第n个元素独立成一个集合,
S
(
n
−
1
,
k
−
1
)
S(n-1,k-1)
S(n−1,k−1)。如果前n-1个元素形成少于
k
−
1
k-1
k−1个集合,则无论如何放置第k个元素,都无法形成k个集合。因此得到递推公式
S
(
n
,
k
)
=
S
(
n
−
1
,
k
−
1
)
+
k
S
(
n
−
1
,
k
)
S(n,k)=S(n-1,k-1)+kS(n-1,k)
S(n,k)=S(n−1,k−1)+kS(n−1,k)。
4、显然,就是第3种情况的扩展,k个盒子,允许空盒子,相当于1~k个盒子,且不允许空盒子的结果之和。
5、隔板法。n个相同球划分成k个不同的非空部分,相当于用k-1个隔板将其隔开。这k-1个隔板可以插入n个球中间的n-1个缝隙中,也就是组合数
C
n
−
1
k
−
1
C_{n-1}^{k-1}
Cn−1k−1。
6、依然是隔板法。这次每个部分可以为空,这样就相当于k-1个隔板可以和这n个球任意排列,也就是组合数
C
n
+
k
−
1
k
−
1
C_{n+k-1}^{k-1}
Cn+k−1k−1。
7、盒子不同,相当于在盒子相同的情况下给盒子编号,这样共有
A
k
k
=
k
!
A_k^k=k!
Akk=k!种编号方法,答案为
k
!
S
(
n
,
k
)
k!S(n,k)
k!S(n,k)。
8、(这个最简单,自己思考吧)
补充
1、贝尔数
B
(
n
)
B(n)
B(n):将n个不同元素划分为若干非空集合的划分方法数。集合个数可以为1、2、…、n。显然,
B
(
n
)
=
∑
i
=
1
n
S
(
n
,
k
)
B(n)=\sum_{i=1}^nS(n,k)
B(n)=∑i=1nS(n,k)。特别地,
B
(
0
)
=
1
B(0)=1
B(0)=1。
贝尔数符合递推公式
B
(
n
+
1
)
=
∑
i
=
0
n
C
n
k
B
(
k
)
B(n+1)=\sum_{i=0}^nC_n^kB(k)
B(n+1)=∑i=0nCnkB(k)。
2、情况7,也就是球不同,盒子不同,且不可以为空的情况,还有一种思考角度,容斥原理。首先考虑k个盒子自由选择的情况,
f
(
0
)
=
k
n
f(0)=k^n
f(0)=kn。然后,考虑至少1个盒子不放的情况,有
C
k
1
(
k
−
1
)
n
C_k^1(k-1)^n
Ck1(k−1)n,这其中又包括至少2个盒子不放的情况,为
C
k
2
(
k
−
2
)
n
C_k^2(k-2)^n
Ck2(k−2)n,以此类推,可得最终结果为
∑
i
=
0
k
(
−
1
)
i
(
k
−
i
)
n
\sum_{i=0}^k(-1)^i(k-i)^n
∑i=0k(−1)i(k−i)n。实现的复杂度:计算
0
−
k
0-k
0−k的n次幂需要
O
(
k
n
)
O(kn)
O(kn)(通过快速幂可以达到
O
(
k
l
o
g
n
)
O(klogn)
O(klogn)),求和需要
O
(
k
)
O(k)
O(k),最终总时间最好可达
O
(
k
l
o
g
n
)
O(klogn)
O(klogn)。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)