题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2048
题目大意:有n个人分别将写了自己名字的字条放进箱子里,求没有一个人恰好拿到自己自己名字的概率。
思想:错排。排列
AC代码:
#include<stdio.h>
#include <stdlib.h>
int main()
{
int i;
int j;
int C;
long long f[21]={0};
f[1]=0;
f[2]=1;
for(i=3;i<21;i++)
f[i]=(i-1)*(f[i-1]+f[i-2]);
scanf("%d",&C);
while(C--)
{
int n;
scanf("%d",&n);
long long sum=1;
for(j=2;j<=n;j++)
sum*=j;
double b=100.0*f[n]/sum;
printf("%.2f%%\n",b);
}
return 0;
}
假设f(n) 是这n个人均拿的 非自己名字 的方法数目。
如果已经有 (n-1) 个人均满足 错排,这时来了第n个人拿着自己名字 ,
他可以和 前(n-1 )个人任意交换,这时的方法数为(n-1)*f(n-1)。
如果(n-1)个人不满足错排,这时第n个人与(n-1)人中其中一个交换后,
即在原先(n-1)个人中,有(n-2)个人满足错排,而这个人可以是这(n-1)
个人中的任意一个。第n个人与他交换即可。所以方法数为(n-1)*f(n-2)
相加得:(n-1)*(f(n-1)+f(n-2))。
总方法数目为:n!