杭电OJ2048

/*
人数从1到4写手动模拟找出递推规律: 
总体上就是得出n的完全错排方案个数, 然后除以n!即可;关键是求n的完全错排方案个数;
第n个人可以选取前n-1个人中任意一个人的字条,第n个人有n-1种选择,假设第n个人取到的是第i个人的字条,
1.这时i可以保留第n个人的字条,剩余的n-2个人完全错排;(要递推就要找是否出现有n-1或n-2完全错排的情况),(i可以保留第n个人的字条的时候满足)(则还要讨论另一种情况若第i个人未保留第n个人的字条) 
2.若第i个人未保留第n个人的字条,则相当于除第n个人之外的剩余n-1个人完全错排(因为第i个人不能保留第n个人的纸条)(第2种情况也联系到递推式,相当于!)
第二种情况以纸条ABCDE为例,
 A选了纸条B,B未选纸条A,则还剩下纸条ACDE,人BCDE,因为此时B不能选纸条A,在完全错排中人B就相当于人A的作用了(错排人A不能选纸条A),
 则纸条ACDE,人BCDE相当于人ACDE与纸条ACDE完全错排 
递推公式为:a[n] = (n-1)*(a[n-1] + a[n-2]);
*/

#include 
using namespace std;

__int64 fac(int n){
	__int64 sum = 1;
	for(int i = 1; i <= n; i++){
		sum = sum*i;
	}	
	return sum;
}

int main(){
	__int64 a[30];
	a[1] = 0;
	a[2] = 1;
	int n;
	int m;
	double res;
	cin >> n;
	for(int i = 0; i < n; i++){
		cin >> m;
		for(int j = 3; j <= m; j++){
			a[j] = (j-1)*(a[j-1] + a[j-2]);
		}
		res = (double)a[m]/fac(m)*100;
		printf("%.2f%%\n",res);//控制格式时"%%"才代表一个百分号 
	}
	return 0;
}

你可能感兴趣的:(杭电OJ)