您的位置:首页 > 其它

HDU 2049 神、上帝以及老天爷 错排

2017-05-08 19:15 239 查看
题意就是:有n个人,然后每个人不能拿到和自己编号相同的字条

错排:对于第一个位子,有n-1种方法,我们假设放了k,然后对于k的位子,我们如果放了1的话,之后就是对于n-2的错排。如果1不放到k,就可以把k的位置看成“第1个位置”,然后就是n-1的错排

f(n)=(n-1)*(f(n-1)+f(n-2))

参考http://blog.csdn.net/cambridgeacm/article/details/7722708

#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <cmath>
using namespace std;
const int maxn = 25;
long long f[maxn];
long long x[maxn];
void ini()
{
f[1]=0;
f[2]=1;
f[3]=2;
x[0]=1;
for(int i=4;i<=20;i++)
f[i]=(i-1)*(f[i-1]+f[i-2]);
for(int i=1;i<=20;i++)
x[i]=i*x[i-1];
}
int main()
{
int C;
scanf("%d",&C);
ini();
while(C--)
{
int n;
scanf("%d",&n);
printf("%.2f%%\n",(double)f
*100/(double)x
);
}
return 0;
}


然后用容斥原理也可以做

d=(1-1/1!+1/2!-1/3!…….+(-1)^n/n!);

就把这个式子求出来就行了

#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstdio>

using namespace std;
#define LL long long
const int maxn = 25;

LL A[maxn];
void init()
{
A[0]=1;
A[1]=1;
for(int i=2;i<=20;i++)
A[i]=A[i-1]*i;
return ;
}
int main()
{
int t;
scanf("%d",&t);
init();
while(t--)
{
int n;
scanf("%d",&n);
double ans=1;
for(int i=1;i<=n;i++){
if(i%2==1)

4000
ans-=(double)1/A[i];
else ans+=(double)1/A[i];
}
printf("%.2f%%\n",ans*100);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: