一.错排原理
何谓错排?错排就是完全乱序,比如有n个元素各有自己的编号,然后有各自相应的位置,位置号等于编号,所有元素的编号与位置号都不相等的情况叫作错排,那么求所有的情况数,则是一个动态规划问题。
当n个编号元素放在n个编号位置,元素编号与位置编号各不对应的方法数用D(n)表示,那么D(n-1)就表示n-1个编号元素放在n-1个编号位置,各不对应的方法数,其它类推.
第一步,把第n个元素放在一个位置,比如位置k,一共有n-1种方法,只要元素号不放入对应的位置即可。
第二步,对于编号为k的元素,这时有两种情况:⑴把它放到位置n,那么,对于剩下的n-1个元素,由于第k个元素放到了位置n,剩下n-2个元素就有D(n-2)种方法;⑵第k个元素不把它放到位置n,这时,对于这n-1个元素,有D(n-1)种方法;
综上得到:
D(n) = (n-1) [D(n-2) + D(n-1)];
特殊地,D(1) = 0, D(2) = 1.
接下来,进行关于错排题目以及一些变形的详解。
二.发邮件
由上可知,这是一个单纯的错排问题,D(n)表示所有情况。假设a的邮件A寄给了其他人,有n种情况,假设其中一种符合的情况,寄给了b,那么得看b的邮件B,如果寄给了a,那么这两人错排成功,那么剩下n-2个人重新按此进行推理,即D(n-2);如果没有寄给a,那么暂时只知道a错排成功,其它n-1个人得重新探索,即D(n-1)。所以D(n)=(n-1)(D(n-1)+D(n-2))。
代码实现:
#-*-coding:utf-8-*-
res=[0,0,1]
for i in range(3,21):
res.append((i-1)*(res[i-1]+res[i-2]))
while True:
try:
n=int(raw_input())
print res[n]
except:
break
三.年会抽奖
如上图所示,这就是一个错排变形的求概率的题。对于n个人错排的情况是D(n),而D(n)=(n-1)(D(n-1)+D(n-2)),而所有的抽奖情况则是n!;所以对于n个人,出现无人获奖的概率是:ans=D(n)/(n!)。
代码实现:
#-*-coding:utf-8-*-
res=[0,0,1]
ans=2
tmp=['0.00%','0.00%','50.00%']
for i in range(3,21):
res.append((i-1)*(res[i-1]+res[i-2]))#求错排情况
ans*=i#求所有抽奖的情况
t=res[i]/float(ans)*100#求无人获奖的概率
t='%.2f'%t
tmp.append(str(t)+'%')
while True:
try:
n=int(raw_input())
print tmp[n]
except:
break
四.考新郎
代码实现:
#-*-coding:utf-8-*-
res=[0,0,1]
for i in range(3,21):
res.append((i-1)*(res[i-1]+res[i-2]))#错排情况
while True:
try:
n,m=map(int,raw_input().split())
ans=1
t=1
#组合问题求n个中选m个新娘可能的情况。
for i in range(n-m+1,n+1):
ans*=i
for i in range(1,m+1):
t*=i
ans=ans/t
ans=ans*res[m]
print ans
except:
break