您的位置:首页 > 其它

杭电 2048 神、上帝以及老天爷(公式法)

2013-08-02 21:47 344 查看
题目地址:

  http://acm.hdu.edu.cn/showproblem.php?pid=2048

  话不多说,http://blog.sina.com.cn/s/blog_69fc13c50100lamw.html

概念:  
全错位排列,n个物质,重新排列顺序,使其均不在原位。
历史:  
被著名数学家欧拉(Leonhard Euler,1707-1783)称为“组合数论的一个妙题”的“装错信封问题”的两个特例.
  “装错信封问题”是由当时最有名的数学家约翰·伯努利(Johann Bernoulli,1667-1748)的儿子丹尼尔·伯努利(DanidBernoulli,1700-1782)提出来的,大意如下:
  个人写了n封不同的信及相应的n个不同的信封,他把这n封信都装错了信封,问都装错信封的装法有多少种?
公式及证明:
  n个相异的元素排成一排a1,a2,...,an,且ai(i=1,2,...,n)不在第i位的排列数为n!(1-1/1!+1/2!-1/3!+...+(-1)^n*1/n!)
  证明:
  设1,2,...,n的全排列t1,t2,...,tn的集合为I,而使ti=i的全排列的集合记为Ai(1<=i<=n),
  则Dn=|I|-|A1∪A2∪...∪An|.
  所以Dn=n!-|A1∪A2∪...∪An|.
  注意到|Ai|=(n-1)!,|Ai∩Aj|=(n-2)!,...,|A1∩A2∩...∩An|=0!=1.
  由容斥原理:
  Dn=n!-|A1∪A2∪...∪An|=n!-C(n,1)(n-1)!+C(n,2)(n-2)!-C(n,3)(n-3)!+...+(-1)^nC(n,n)*0!
  =n!(1-1/1!+1/2!-1/3!+...+(-1)^n*1/n!

  

  注:理论看的似懂非懂的,但是我记住了公式

  

#include <stdio.h>
//装错信封的问题:公式法
double fac(int n)
{
double s = 1.0;
int i;
for( i = 2; i <= n; i++ )
s = s * i;
return s;
}

int main()
{
int c, n, i;
double s;
scanf( "%d", &c );
while( c-- )
{
scanf("%d", &n);
s = 1.0;
for( i = 1; i <= n; i++ )
if( i % 2 )
s = s - 1/fac(i);
else
s = s + 1/fac(i);
printf( "%.2lf%%\n", s*100 );
}
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: