这几天终于有时间来记录一些有趣的问题了,是之前笔试的一道题的原型。没有系统的总结,对我来说还真的很难在笔试时候打出来(阅历不够啊)
本文基于:https://blog.csdn.net/zwz_511/article/details/46240927
里的理论进行一定补充及python实现
1. 球同,盒同,盒非空
Pm(N)的表示,m个同盒里放N个同球(非空)有多少种放法(因为盒同,所以[0,1,0],[0,0,1]…只算一种放法)。
运用递归。当盒数大于球数,是不可能成立的。
得到球与盒的差值(因为盒非空,所以每个盒先放进一个球)
如果目前盒的数量大于这个差值,那么就让盒数等于这个差值
如果盒等于1或0(这个0是为了防止原本和盒数和球数相同情况)返回1,代表这是1种。
盒为2,绝对不会超过球数的一半(5球2种,3球1种……)。
接着就是按公式的递归。
代码如下:
def ballandbox(box,ball):
if box > ball:
return -1
ball2 = ball - box
if box > ball2:
box = ball2
if box == 1 or box == 0:
return 1
if box == 2:
return ball // 2
result = 0
for i in range(box):
result += ballandbox(i+1,ball2)
return result
模拟一遍。如4盒7球:
P4(7) → box=4,ball =7
P4(7)= P1(3)+P2(3)+P3(3) → ball2 = 7-4=3,box = 3 进入迭代,result = 函数(1,3)+(2,3)+(3,3)
1 + 1 + 1 → box == 1,返回1,box == 2,返回3//2=1,box == 3,球数也为3,所以box == 0,返回1
2. 球同,盒同,盒可空
在1的基础上,该情况的公式是Pm(m+N)的表示,m个盒里放m+N个球(非空)有多少种放法。
意思是,N+m个球先把每个盒都放1个球,也就是放进m个球,剩下的N个球再放就相当于是盒可空的情况。
也就是在1的代码基础上,将输入改为m+N,并且当盒大于球数时,直接相当于盒等于球时的情况。
def ballandbox(box,ball):
if box > ball:
box = ball
ball2 = ball - box
if box > ball2:
box = ball2
if box == 1 or box == 0:
return 1
if box == 2:
return ball // 2
result = 0
for i in range(box):
result += ballandbox(i+1,ball2)
return result
3.球同,盒不同,盒非空
高中题,插板法
box个盒子,ball个球。就相当于ball个球中间有ball-1个空,从这个些个空中挑出box-1个,剩下的类数为box个。对盒子的排序没有要求,所以公式也就是 C b o x − 1 b a l l − 1 C_{box-1}^{ball-1} Cbox−1ball−1
def main(box,ball):
box = box - 1
ball = ball -1
return ballandbox3(box,ball)
def ballandbox3(box,ball):
if ball == 1:
return box
elif box == 1 or ball == 0:
return 1
else:
return ballandbox3(box-1