首先,书不同是个多余条件,完全可以当做3本相同的语文书,4本相同的数学书,5本相同的英语书。至于为什么可以这样,我可以通俗的解释一下,书不同时的任何一个放书状态,都包含在书相同的放书状态中;而且完全组成之。这种解释不知你看得懂不。反正,当相同的书处理。
从左往右排
总的排列数:C(12,3)*C(9,4)
同科书不在一起的排列数:最快方法是穷举,途径是用函数递归。
设语文x本,数学y本,英语z本,构成同科不在一起的排列数为f(x,y,z)
通过画出二叉树,
可以总结出,f(x,y,z) =f(x,y-1,z-1)+f(x-1,y-1,z-1,第一本不能排语)
+f(x-1,y,z-1)+f(x-1,y-1,z-1,第一本不能排数)
+f(x-1,y-1,z)+f(x-1,y-1,z-1,第一本不能排外)
=f(x,y-1,z-1)+f(x-1,y,z-1)+f(x-1,y-1,z)
+2*f(x-1,y-1,z-1)
这就是我推出来的迭代公式。
f(3,4,5)=588;
所以概率=f(3,4,5)/【C(12,3)*C(9,4)】=7/990
你可以在程序结果里看到当书本数较小时的结果,可以手动验证。
附录:
一下是求f的c程序
#include
int f(int a,int b,int c)
{ int x,y,z;
if((a==0)&&(b==0)&&(c==0))
return(0);
else if((a==0)&&(b==0)&&(c==1))
return(1);
else if((a==0)&&(b==1)&&(c==0))
return(1);
else if((a==1)&&(b==0)&&(c==0))
return(1);
else if((a==0)&&(b==1)&&(c==1))
return(2);
else if((a==1)&&(b==1)&&(c==0))
return(2);
else if((a==1)&&(b==0)&&(c==1))
return(2);
else if((a==1)&&(b==1)&&(c==1))
return(6);
else if(b==0)
{if((a==c+1)||(c==a+1))
return(1);
else
if(a==c) return(2);
else return(0);
}
else if(a==0)
{if((b==c+1)||(c==b+1))
return(1);
else
if(b==c) return(2);
else return(0);
}
else if(c==0)
{if((b==a+1)||(a==b+1))
return(1);
else
if(a==b) return(2);
else return(0);
}
else
{
x=a-1;if(x<0)x=0;
y=b-1;if(y<0)x=0;
z=c-1;if(z<0)x=0;
return(f(a,y,z)+f(x,b,z)+f(x,y,c)+2*f(x,y,z));
}
}
void main()
{
int m,q,w,e;
for(q=0;q<4;q++)
for(w=0;w<5;w++)
for(e=0;e<6;e++)
{ m=f(q,w,e);
printf("f(%d,%d,%d)=%d\n",q,w,e,m);}
}