关于错排:
就是把n个球(编号1--n)放到n个盒子(编号1---n)里面,要求球的号码与合资的号码不相同。
公式:
当n个编号元素放在n个编号位置,元素编号与位置编号各不对应的方法数用M(n)表示,那么M(n-1)就表示n-1个编号元素放在n-1个编号位置,各不对应的方法数,其它类推.
第一步,把第n个元素放在一个位置,比如位置k,一共有n-1种方法;
第二步,放编号为k的元素,这时有两种情况⑴把它放到位置n,那么,对于剩下的n-1个元素,由于第k个元素放到了位置n,剩下n-2个元素就有M(n-2)种方法;⑵第k个元素不把它放到位置n,这时,对于这n-1个元素,有M(n-1)种方法;
综上得到
M(n)=(n-1)[M(n-2)+M(n-1)]
特殊地,M⑴=0,M⑵=1
为方便起见,设M(k)=k!N(k),(k=1,2,…,n)
则N⑴=0,N⑵=1/2
n>=3时,n!N(n)=(n-1)(n-1)!N(n-1)+(n-1)!N(n-2)
即 nN(n)=(n-1)N(n-1)+N(n-2)
于是有N(n)-N(n-1)=-[N(n-1)-N(n-2)]/n=(-1/n)[-1/(n-1)][-1/(n-2)]…(-1/3)[N⑵-N⑴]=(-1)^n/n!
因此 N(n-1)-N(n-2)=(-1)^(n-1)/(n-1)!
N⑵-N⑴=(-1)^2/2!
相加,可得 N(n)=(-1)^2/2!+…+(-1)^(n-1)/(n-1)!+(-1)^n/n!
因此M(n)=n![(-1)^2/2!+…+(-1)^(n-1)/(n-1)!+(-1)^n/n!]
可以得到错排公式为M(n)=n!(1/2!-1/3!+…..+(-1)^n/n!)
HDU2048
#include<iostream>
#include<cmath>
#include<cstdio>
using namespace std;
double function(int n)
{
double ans=1;
for(int i=1; i<=n; i++)
{
ans*=i;
}
return ans;
}
int main()
{
int t,n;
double sum;
cin>>t;
while(t--)
{
cin>>n;
sum=0;
//cout<<function(n)<<endl;
for(int i=2; i<=n; i++)
{
if(i&1)
sum+=-1/function(i);
else
sum+=1/function(i);
}
// cout<<sum<<endl;
// printf("%.2f%%\n",function(n)*sum);
printf("%.2f%%\n",100*sum);
}
return 0;
}