杭电 2048
来源:互联网 发布:java开发工程师 拉钩 编辑:程序博客网 时间:2024/06/05 15:22
题目:
神、上帝以及老天爷
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 40601 Accepted Submission(s): 16652
为了活跃气氛,组织者举行了一个别开生面、奖品丰厚的抽奖活动,这个活动的具体要求是这样的:
首先,所有参加晚会的人员都将一张写有自己名字的字条放入抽奖箱中;
然后,待所有字条加入完毕,每人从箱中取一个字条;
最后,如果取得的字条上写的就是自己的名字,那么“恭喜你,中奖了!”
大家可以想象一下当时的气氛之热烈,毕竟中奖者的奖品是大家梦寐以求的Twins签名照呀!不过,正如所有试图设计的喜剧往往以悲剧结尾,这次抽奖活动最后竟然没有一个人中奖!
我的神、上帝以及老天爷呀,怎么会这样呢?
不过,先不要激动,现在问题来了,你能计算一下发生这种情况的概率吗?
不会算?难道你也想以悲剧结尾?!
12
50.00%
这个题就是运用错排公式(递推)错排规律如下:
当n个编号元素放在n个编号位置,元素编号与位置编号各不对应的方法数用D(n)表示,那么D(n-1)就表示n-1个编号元素放在n-1个编号位置,各不对应的方法数,其它类推.
第一步,把第n个元素放在一个位置,比如位置k,一共有n-1种方法;
第二步,放编号为k的元素,这时有两种情况:⑴把它放到位置n,那么,对于剩下的n-1个元素,由于第k个元素放到了位置n,剩下n-2个元素就有D(n-2)种方法;⑵第k个元素不把它放到位置n,这时,对于这n-1个元素,有D(n-1)种方法;
综上得到
D(n) = (n-1) [D(n-2) + D(n-1)]
特殊地,D(1) = 0, D(2) = 1.
下面通过这个递推关系推导通项公式:
为方便起见,设D(k) = k! N(k), k = 1, 2, …, n,
则N(1) = 0, N(2) = 1/2.
n ≥ 3时,n! N(n) = (n-1) (n-1)! N(n-1) + (n-1)! N(n-2)
即 nN(n) = (n-1) N(n-1) + N(n-2)
于是有N(n) - N(n-1) = - [N(n-1) - N(n-2)] / n = (-1/n) [-1/(n-1)] [-1/(n-2)]…(-1/3) [N(2) - N(1)] = (-1)^n / n!.
因此
N(n-1) - N(n-2) = (-1)^(n-1) / (n-1)!,
N(2) - N(1) = (-1)^2 / 2!.
相加,可得
N(n) = (-1)^2/2! + … + (-1)^(n-1) / (n-1)! + (-1)^n/n!
因此
D(n) = n! [(-1)^2/2! + … + (-1)^(n-1)/(n-1)! + (-1)^n/n!].
此即错排公式。
折叠编辑本段容斥原理
用容斥原理也可以推出错排公式:
正整数1, 2, 3, ……, n的全排列有 n! 种,其中第k位是k的排列有 (n-1)! 种;当k分别取1, 2, 3, ……, n时,共有n*(n-1)!种排列是至少放对了一个的,由于所求的是错排的种数,所以应当减去这些排列;但是此时把同时有两个数不错排的排列多排除了一次,应补上;在补上时,把同时有三个数不错排的排列多补上了一次,应排除;……;继续这一过程,得到错排的排列种数为
D(n) = n! - n!/1! + n!/2! - n!/3! + … + (-1)^n*n!/n! = ∑(k=2~n) (-1)^k * n! / k!,
即D(n) = n! [1/0! - 1/1! + 1/2! - 1/3! + 1/4! + ... + (-1)^n/n!].
其中,∑表示连加符号,k=2~n是连加的范围;0! = 1,可以和1!相消。
折叠编辑本段简化公式
错排公式的原形为D(n) = n! (1/0! - 1/1! + 1/2! - 1/3! - ..... + (-1)^n/n!),当n很大时计算就很不方便。一个供参考的简化后的公式是D(n) = [n!/e+0.5] ,其中e是自然对数的底,[x]为x的整数部分。
证明:
由于1/e = e^(-1) = 1/0! - 1/1! + 1/2! - 1/3! - ..... + (-1)^n/n! + Rn(-1),
其中Rn(-1)是余项,等于(-1)^(n+1) * e^u / (n+1)!,且u∈(-1, 0).
所以,D(n) = n! * e^(-1) - (-1)^(n+1) * e^u / (n+1), u∈(-1, 0).
而|n! Rn| = |(-1)^(n+1) * e^u / (n+1)| = e^u / (n+1) ∈ (1/[e(n+1)], 1/(n+1)),可知即使在n=1时,该余项(的绝对值)也小于1/2。
因此,无论n! Rn是正是负,n! / e + 1/2的整数部分都一定与M(n)相同。
对于比较小的n,结果及简单解释是:
D(0) = 1(所有的元素都放回原位、没有摆错的情况)
D(1) = 0(只剩下一个元素,无论如何也不可能摆错)
D(2) = 1(两者互换位置)
D(3) = 2(ABC变成BCA或CAB)
D(4) = 9
D(5) = 44
D(6) = 265
D(7) = 1854
D(8) = 14833
D(9) = 133496
D(10) = 1334961
#include<iostream>#include<iomanip>using namespace std;double jiecheng(double m){ double sum=1.0,i; for(i=1;i<=m;i++) sum=sum*i; return sum;}int main(){ double s[33],num; int i,n,a; cin>>n; s[1]=0.0; s[2]=1.0; for(i=3;i<=20;i++) { s[i]=(i-1)*(s[i-1]+s[i-2]); } while(n--) { cin>>a; num=jiecheng(a); cout<<fixed<<setprecision(2)<<s[a]/num*100<<"%"<<endl; } return 0;}c语言代码:
#include<stdio.h>_int64 jiechen(int i){int j;_int64 score=1;for(j=1;j<=i;j++)score=score*j;return score;}int main(){int n,m,i,j;_int64 score;_int64 s[1000]={0};s[1]=0;s[2]=1;for(i=3;i<=20;i++){s[i]=(i-1)*(s[i-1]+s[i-2]);}while(scanf("%d",&n)!=EOF){while(n--){scanf("%d",&m);score=jiechen(m);printf("%.2lf%%\n",1.0*s[m]/score*100);}}return 0;}
- 杭电2048
- 杭电2048
- 杭电 2048
- 杭电2048
- 杭电ACM 2048
- 杭电 2048
- 杭电 2048 数塔
- 杭电2048解题报告
- 杭电2048数塔
- 杭电
- 杭电
- 杭电
- 杭电 2048 神、上帝以及老天爷
- 杭电2048//C++带小数点输出
- 杭电 2048 神、上帝以及老天爷
- 杭电2048神、上帝以及老天爷
- 杭电2048 神、上帝以及老天爷
- 【杭电】[2048]神、上帝以及老天爷
- 利用一条SQL从表中抽取一定数据
- Plan
- webpack项目搭建
- jq 点击元素其他区域 该元素隐藏
- python学习5——集合
- 杭电 2048
- HBase性能优化方法总结
- 详解Hive-Driver——细读Hive源码(四)
- OFBIZ
- System.Data.SQLite错误,
- jzoj1277 最高的奶牛
- php 把$_POST参数解析出来
- AVL树的旋转图解和简单实现
- 第四章 类和对象