杭电OJ 2048 完全错排的可能性
/*
人数从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 <iostream> #include <cstdio> using namespace std; const int MAXN = 20 + 5; long long situation[MAXN]; void Initial() { situation[1] = 0; situation[2] = 1; for(int i = 3; i < MAXN; ++i) { //第n个人有n-1种选择 situation[i] = (i - 1) * (situation[i - 1] + situation[i - 2]); } } //20的阶乘可能超过int范围 long long JieMutipe(int x) { long long ans = 1; for(int i = 2; i <= x; ++i) { ans *= i; } return ans; } int main() { Initial(); int c, n; cin >> c; while(c--) { cin >> n; double answer = (double) situation[n] / JieMutipe(n) * 100; printf("%.2f%%\n", answer); } return 0; }
要注意用long long保存数据,否则可能越界
参考资料:
杭电OJ2048
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具