现在的位置: 首页 > 综合 > 正文

HDU/HDOJ 2068 错排公式

2018年01月20日 ⁄ 综合 ⁄ 共 1078字 ⁄ 字号 评论关闭

 

RPG的错排

Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 3015    Accepted Submission(s): 1245

Problem Description
今年暑假杭电ACM集训队第一次组成女生队,其中有一队叫RPG,但做为集训队成员之一的野骆驼竟然不知道RPG三个人具体是谁谁。RPG给他机会让他猜猜,第一次猜:R是公主,P是草儿,G是月野兔;第二次猜:R是草儿,P是月野兔,G是公主;第三次猜:R是草儿,P是公主,G是月野兔;......可怜的野骆驼第六次终于把RPG分清楚了。由于RPG的带动,做ACM的女生越来越多,我们的野骆驼想都知道她们,可现在有N多人,他要猜的次数可就多了,为了不为难野骆驼,女生们只要求他答对一半或以上就算过关,请问有多少组答案能使他顺利过关。
 

Input
输入的数据里有多个case,每个case包括一个n,代表有几个女生,(n<=25), n = 0输入结束。
 

Sample Input
1 2 0
 

Sample Output
1 1
 

Author
Rabbit
 

Source
 
我的做法是:
求0到n/2的所有错排和
注意到对于i个人的错排的时候,还应该在错排前面乘上一个C(n,i)
代表选取i个人进行错排
 
我的代码:
#include<stdio.h>
#include<math.h>
#define e exp(1.0)

__int64 ans[30];
__int64 f[30];

double p(int n)
{
	int i;
	double res=1.0;
	for(i=1;i<=n;i++)
		res=res*i;
	return res;
}

__int64 C(int n,int r)
{
	__int64 res=1,i;
	for(i=1;i<=r;i++)
	{
		res=res*(n-i+1);
		res=res/i;
	}
	return res;
}

void init()
{
	int i,j;
	for(i=1;i<=13;i++)
		f[i]=(__int64)(p(i)/e+0.5);
	ans[1]=1,f[0]=1;
	for(i=2;i<=25;i++)
	{
		for(j=0;j<=i/2;j++)
			ans[i]=ans[i]+f[j]*C(i,j);
	}
}

int main()
{
	int n;
	init();
	while(scanf("%d",&n)!=EOF)
	{
		if(n==0)
			break;
		printf("%I64d\n",ans[n]);
	}
	return 0;
}

抱歉!评论已关闭.