#include <stdio.h>
long long a[25] = {0, 0, 1};
long long f[25] = {0, 1};
void fun()
{
for(int i = 3; i <= 20; i++)
a[i] = (i - 1)*a[i - 1] + (i - 1)*a[i - 2];
}
void sum()
{
for(int i = 2; i <= 20; i++)
f[i] = i*f[i-1];
}
int main()
{
fun();
sum();
int t, n;
scanf("%d", &t);
while(t--) {
scanf("%d", &n);
printf("%.2f%%\n", (double)a[n]/f[n]*100);
}
return 0;
}
解题思路
a[n]代表有n个人拿到错误的名字
a[1] = 0
A |
a[2] = 1
AB | BA |
a[3] = 2
ABC | ACB | BAC | BCA | CAB | CBA |
当有n个人参加时,符合的条件:
- 前n-1个人都拿到了错误的名字,此时第n个人可以任意的和其中一个人换
a[n]=(n−1)∗a[n−1] a[n] = (n-1)*a[n-1] a[n]=(n−1)∗a[n−1] - 前n-1个人只有一个人拿到了自己的名字,此时第n个人就和这个人换
a[n]=(n−1)∗a[n−2] a[n] = (n-1)*a[n-2] a[n]=(n−1)∗a[n−2]
那么,总数
a[n]=(n−1)∗(a[n−1]+a[n−2]) a[n] = (n-1)*(a[n - 1] + a[n - 2]) a[n]=(n−1)∗(a[n−1]+a[n−2])
n个人,共有n!中取法,那么
P=a[n]/n!
P=a[n]/n!
P=a[n]/n!