题目
题解思路
对于递推的题 我们在找关系式的时候一定要找那些不变的量
n个人n个票,问所有人都拿错票的方法数?
n个人全都拿错即错排可以描述为f(n),那么它的来源必定是两种可能 :
第一种:前n-1个人已经错排那么必然第n个人拿的他自己的票。
第二种:第n个人拿的不是自己的票,那么必然前n-1个人之一的票被第n个人拿着。
对于case1:只需第n个人的票与前n-1人之一互换,n个人均能成错排,有f(n-1)(n-1)种方法。
对于case2 :因为第n个人拿着前n-1人当中某一人的票,那么只能和除这人之外的人互换票,才能成为n票错牌的来源,
n-1人当中除那人外f(n-2)错排,且n-1某个人都有可能票被n拿着。此时f(n-2)(n-1);
那么f(n)=(n-1)*(f(n-1)+f(n-2));
这样的话我们找到了错排方法的总数,剩下除以方法的总数 (n 的 阶乘 ) 就可以得出答案了 ,这题居然还卡精度把我整吐了。
对于每个测试实例,请输出发生这种情况的百分比
AC代码
#include<iostream>
#include <cstdio>
using namespace std;
int main()
{
int n;
double ls[21] = { 0, 0, 1 }; //错排方法数
double gq[21] = { 1, 1, 2 }; //方法总数
for (int i = 3; i<21; i++)
{
gq[i] = gq[i - 1] * i;
ls[i] = (i - 1)*(ls[i - 1] + ls[i - 2]);
}
cin >> n; int t;
while (n--)
{
cin >> t;
printf("%.2lf%%\n", ls[t] / gq[t] * 100);
}
return 0;
}