您的位置:首页 > 其它

hdu2048 神、上帝以及老天爷【错排问题】【容斥原理】

2018-01-07 15:21 309 查看

解题思路:

即是求错排数。

先是递推的做法

将错排方法数记为D(n)。

1. 把第n个元素放在一个位置,比如k,有n-1种方法。

2. 编号为k的元素有两种放法。

<1> 把它放到位置n。那么对于剩下的n-2个元素,就有D(n-2)种方法。

<2> 不把它放到位置n。那么对于剩下的n-1个元素,就有D(n-1)种方法。

由此可得递推公式:

D(n) = (n-1) * ( D(n-1) + D(n-2) ).


还有容斥的做法:

正整数1, 2, 3, ……, n的全排列有 n! 种,其中第k位是k的排列有 (n-1)! 种;当k分别取1, 2, 3, ……, n时,共有n∗(n−1)!种排列是至少放对了一个的,由于所求的是错排的种数,所以应当减去这些排列;但是此时把同时有两个数不错排的排列多排除了一次,应补上方案数C2n(n−2)!=n!2!;在补上时,把同时有三个数不错排的排列多补上了一次,同理应排除frac{n!}{3!};……;继续这一过程,得到错排的排列种数为:

D(n)=∑i=0n(−1)in!i!

#include<bits/stdc++.h>
#define ll long long
using namespace std;

int T,n;
ll num,fac[25];
double ans;

int main()
{
//freopen("lx.in","r",stdin);
fac[0]=1;
for(int i=1;i<=20;i++)fac[i]=fac[i-1]*i;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);num=0;
for(int i=0;i<=n;i++)num+=fac
/fac[i]*(i&1?-1:1);
ans=num*1.0/fac
*100;
printf("%.2f%%\n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: