题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2048
思路:
假设已经错排了n-1个人,第n个人拿着自己的字条,那么第n个人与前n-1个人其中一个交换即全部错排,即(n-1)an(n-1)种方法;如果前n-1人中,有一个人拿着自己的字条,这个人和第n个人交换字条即全部错排,即(n-1)an(n-2)种方法。(an(n)为错排方法个数)
综上:an(n)=(n-1)*[an(n-1)+an(n-2)]
代码:
#include
int main(void)
{
int n, i, T;
double an[21] = { 0,0,1 };
long long sum[21] = {0,1,2 };
for (i = 3; i <= 20; i++)
{
an[i] = (i - 1) * (an[i - 1] + an[i - 2]);
sum[i] = sum[i-1]*i;
}
scanf("%d", &T);
while (T--)
{
scanf("%d", &n);
printf("%.2f%%\n", (an[n] / sum[n]) * 100);
}
return 0;
}